<commit_before>// from src/libsyntax/ext/tt/macro_rules.rs

use std::cell::RefCell;
use syntax::parse::parser::Parser;
use syntax::parse::token;
use syntax::ast;
use syntax::ptr::P;

use syntax::ext::base::MacResult;
use syntax::util::small_vector::SmallVector;

macro_rules! panictry {
    ($e:expr) => ({
        use std::result::Result::{Ok, Err};
        use syntax::errors::FatalError;
        match $e {
            Ok(e) => e,
            Err(mut e) => {
                   e.emit();
                   panic!(FatalError);
               }
        }
    })
}

pub struct ParserAnyMacro<'a> {
    parser: RefCell<Parser<'a>>,
}

impl<'a> ParserAnyMacro<'a> {
    pub fn new(p: Parser<'a>) -> ParserAnyMacro<'a> {
        ParserAnyMacro {
            parser: RefCell::new(p)
        }
    }
    /// Make sure we don't have any tokens left to parse, so we don't
    /// silently drop anything. `allow_semi` is so that "optional"
    /// semicolons at the end of normal expressions aren't complained
    /// about e.g. the semicolon in `macro_rules! kapow { () => {
    /// panic!(); } }` doesn't get picked up by .parse_expr(), but it's
    /// allowed to be there.
    fn ensure_complete_parse(&self, allow_semi: bool) {
        let mut parser = self.parser.borrow_mut();
        if allow_semi && parser.token == token::Semi {
            parser.bump();
        }
        if parser.token != token::Eof {
            let token_str = parser.this_token_to_string();
            let msg = format!("macro expansion ignores token `{}` and any \
                               following",
                              token_str);
            let span = parser.span;
            parser.span_err(span, &msg[..]);
        }
    }
}

impl<'a> MacResult for ParserAnyMacro<'a> {
    fn make_expr(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Expr>> {
        let ret = self.parser.borrow_mut().parse_expr().unwrap();
        self.ensure_complete_parse(true);
        Some(ret)
    }
    fn make_pat(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Pat>> {
        let ret = self.parser.borrow_mut().parse_pat().unwrap();
        self.ensure_complete_parse(false);
        Some(ret)
    }
    fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
        let mut ret = SmallVector::zero();
        while let Some(item) = self.parser.borrow_mut().parse_item().unwrap() {
            ret.push(item);
        }
        self.ensure_complete_parse(false);
        Some(ret)
    }

    fn make_impl_items(self: Box<ParserAnyMacro<'a>>)
                       -> Option<SmallVector<P<ast::ImplItem>>> {
        let mut ret = SmallVector::zero();
        loop {
            let mut parser = self.parser.borrow_mut();
            match parser.token {
                token::Eof => break,
                _ => ret.push(panictry!(parser.parse_impl_item()))
            }
        }
        self.ensure_complete_parse(false);
        Some(ret)
    }

    fn make_stmts(self: Box<ParserAnyMacro<'a>>)
                 -> Option<SmallVector<P<ast::Stmt>>> {
        let mut ret = SmallVector::zero();
        loop {
            let mut parser = self.parser.borrow_mut();
            match parser.token {
                token::Eof => break,
                _ => match parser.parse_stmt() {
                    Ok(maybe_stmt) => match maybe_stmt {
                        Some(stmt) => ret.push(stmt),
                        None => (),
                    },
                    Err(_) => break,
                }
            }
        }
        self.ensure_complete_parse(false);
        Some(ret)
    }
}
<commit_msg>Update for nightly 2/22/2016.<commit_after>// from src/libsyntax/ext/tt/macro_rules.rs

use std::cell::RefCell;
use syntax::parse::parser::Parser;
use syntax::parse::token;
use syntax::ast;
use syntax::ptr::P;

use syntax::ext::base::MacResult;
use syntax::util::small_vector::SmallVector;

macro_rules! panictry {
    ($e:expr) => ({
        use std::result::Result::{Ok, Err};
        use syntax::errors::FatalError;
        match $e {
            Ok(e) => e,
            Err(mut e) => {
                   e.emit();
                   panic!(FatalError);
               }
        }
    })
}

pub struct ParserAnyMacro<'a> {
    parser: RefCell<Parser<'a>>,
}

impl<'a> ParserAnyMacro<'a> {
    pub fn new(p: Parser<'a>) -> ParserAnyMacro<'a> {
        ParserAnyMacro {
            parser: RefCell::new(p)
        }
    }
    /// Make sure we don't have any tokens left to parse, so we don't
    /// silently drop anything. `allow_semi` is so that "optional"
    /// semicolons at the end of normal expressions aren't complained
    /// about e.g. the semicolon in `macro_rules! kapow { () => {
    /// panic!(); } }` doesn't get picked up by .parse_expr(), but it's
    /// allowed to be there.
    fn ensure_complete_parse(&self, allow_semi: bool) {
        let mut parser = self.parser.borrow_mut();
        if allow_semi && parser.token == token::Semi {
            parser.bump();
        }
        if parser.token != token::Eof {
            let token_str = parser.this_token_to_string();
            let msg = format!("macro expansion ignores token `{}` and any \
                               following",
                              token_str);
            let span = parser.span;
            parser.span_err(span, &msg[..]);
        }
    }
}

impl<'a> MacResult for ParserAnyMacro<'a> {
    fn make_expr(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Expr>> {
        let ret = self.parser.borrow_mut().parse_expr().unwrap();
        self.ensure_complete_parse(true);
        Some(ret)
    }
    fn make_pat(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Pat>> {
        let ret = self.parser.borrow_mut().parse_pat().unwrap();
        self.ensure_complete_parse(false);
        Some(ret)
    }
    fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
        let mut ret = SmallVector::zero();
        while let Some(item) = self.parser.borrow_mut().parse_item().unwrap() {
            ret.push(item);
        }
        self.ensure_complete_parse(false);
        Some(ret)
    }

    fn make_impl_items(self: Box<ParserAnyMacro<'a>>)
                       -> Option<SmallVector<ast::ImplItem>> {
        let mut ret = SmallVector::zero();
        loop {
            let mut parser = self.parser.borrow_mut();
            match parser.token {
                token::Eof => break,
                _ => ret.push(panictry!(parser.parse_impl_item()))
            }
        }
        self.ensure_complete_parse(false);
        Some(ret)
    }

    fn make_stmts(self: Box<ParserAnyMacro<'a>>)
                 -> Option<SmallVector<ast::Stmt>> {
        let mut ret = SmallVector::zero();
        loop {
            let mut parser = self.parser.borrow_mut();
            match parser.token {
                token::Eof => break,
                _ => match parser.parse_stmt() {
                    Ok(maybe_stmt) => match maybe_stmt {
                        Some(stmt) => ret.push(stmt),
                        None => (),
                    },
                    Err(_) => break,
                }
            }
        }
        self.ensure_complete_parse(false);
        Some(ret)
    }
}
<|endoftext|>


<commit_before>//! A trait that can be used to parse an item from an input.

#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::convert::TryInto;

use crate::error::TryFromParsed;
use crate::format_description::{well_known, FormatItem};
use crate::parsing::shim::SliceStripPrefix;
use crate::parsing::{Parsed, ParsedItem};
use crate::{error, Date, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};

/// Seal the trait to prevent downstream users from implementing it, while still allowing it to
/// exist in generic bounds.
pub(crate) mod sealed {

    #[allow(clippy::wildcard_imports)]
    use super::*;

    /// Parse the item using a format description and an input.
    #[cfg_attr(__time_03_docs, doc(cfg(feature = "parsing")))]
    pub trait Parsable {
        /// An error that may be returned when parsing.
        type Error: Into<error::Parse>;

        /// Parse the item into the provided [`Parsed`] struct.
        ///
        /// This method can be used to parse part of a type without parsing the full value.
        fn parse_into<'a>(
            &self,
            input: &'a [u8],
            parsed: &mut Parsed,
        ) -> Result<&'a [u8], Self::Error>;

        /// Parse the item into a new [`Parsed`] struct.
        ///
        /// This method can only be used to parse a complete value of a type. If any characters
        /// remain after parsing, an error will be returned.
        fn parse(&self, input: &[u8]) -> Result<Parsed, error::Parse> {
            let mut parsed = Parsed::new();
            match self.parse_into(input, &mut parsed) {
                Ok(remaining) if remaining.is_empty() => Ok(parsed),
                Ok(_) => Err(error::Parse::UnexpectedTrailingCharacters),
                Err(err) => Err(err.into()),
            }
        }

        /// Parse a [`Date`] from the format description.
        fn parse_date(&self, input: &[u8]) -> Result<Date, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`Time`] from the format description.
        fn parse_time(&self, input: &[u8]) -> Result<Time, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`UtcOffset`] from the format description.
        fn parse_offset(&self, input: &[u8]) -> Result<UtcOffset, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`PrimitiveDateTime`] from the format description.
        fn parse_date_time(&self, input: &[u8]) -> Result<PrimitiveDateTime, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`OffsetDateTime`] from the format description.
        fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }
    }
}

impl sealed::Parsable for FormatItem<'_> {
    type Error = error::ParseFromDescription;

    fn parse_into<'a>(
        &self,
        mut input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], Self::Error> {
        match self {
            Self::Literal(literal) => {
                input = input
                    .strip_prefix_(literal)
                    .ok_or(error::ParseFromDescription::InvalidLiteral)?;
            }
            Self::Component(component) => input = parsed.parse_component(input, *component)?,
            Self::Compound(compound) => input = compound.parse_into(input, parsed)?,
        }
        Ok(input)
    }
}

impl sealed::Parsable for &[FormatItem<'_>] {
    type Error = error::ParseFromDescription;

    fn parse_into<'a>(
        &self,
        mut input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], Self::Error> {
        for item in self.iter() {
            input = item.parse_into(input, parsed)?;
        }
        Ok(input)
    }
}

#[cfg(feature = "alloc")]
#[cfg_attr(__time_03_docs, doc(cfg(feature = "alloc")))]
impl sealed::Parsable for Vec<FormatItem<'_>> {
    type Error = error::ParseFromDescription;

    fn parse_into<'a>(
        &self,
        input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], Self::Error> {
        self.as_slice().parse_into(input, parsed)
    }
}

impl sealed::Parsable for well_known::Rfc3339 {
    type Error = error::ParseFromDescription;

    fn parse_into<'a>(
        &self,
        input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], Self::Error> {
        use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral};
        use crate::parsing::combinator::{
            any_digit, ascii_char, ascii_char_ignore_case, exactly_n_digits, sign,
        };

        let dash = ascii_char(b'-');
        let colon = ascii_char(b':');

        let input = exactly_n_digits(4)(input)
            .ok_or(InvalidComponent("year"))?
            .assign_value_to_with(&mut parsed.year, |year: u32| year as i32);
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("month"))?
            .assign_value_to(&mut parsed.month);
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("day"))?
            .assign_value_to(&mut parsed.day);
        let input = ascii_char_ignore_case(b'T')(input)
            .ok_or(InvalidLiteral)?
            .unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("hour"))?
            .assign_value_to(&mut parsed.hour_24);
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("minute"))?
            .assign_value_to(&mut parsed.minute);
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("second"))?
            .assign_value_to_with(&mut parsed.second, |second| {
                // The RFC explicitly allows leap seconds. We don't support them, so treat it as
                // the previous second.
                if second == 60 { 59 } else { second }
            });
        let input = if let Some(ParsedItem(input, ())) = ascii_char(b'.')(input) {
            let ParsedItem(mut input, mut value) = any_digit(input)
                .ok_or(InvalidComponent("subsecond"))?
                .map(|v| v as u32 * 100_000_000);

            let mut multiplier = 10_000_000;
            while let Some(ParsedItem(new_input, digit)) = any_digit(input) {
                value += (digit - b'0') as u32 * multiplier;
                input = new_input;
                multiplier /= 10;
            }

            ParsedItem(input, value).assign_value_to(&mut parsed.subsecond)
        } else {
            input
        };

        if let Some(ParsedItem(input, ())) = ascii_char_ignore_case(b'Z')(input) {
            parsed.offset_hour = Some(0);
            parsed.offset_minute = Some(0);
            parsed.offset_second = Some(0);
            return Ok(input);
        }

        let ParsedItem(input, offset_sign) = sign(input).ok_or(InvalidComponent("offset_hour"))?;
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("offset_hour"))?
            .assign_value_to_with(&mut parsed.offset_hour, |offset_hour: u8| {
                if offset_sign == b'-' {
                    -(offset_hour as i8)
                } else {
                    offset_hour as _
                }
            });
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("offset_minute"))?
            .assign_value_to(&mut parsed.offset_minute);

        Ok(input)
    }

    fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> {
        use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral};
        use crate::parsing::combinator::{
            any_digit, ascii_char, ascii_char_ignore_case, exactly_n_digits, sign,
        };

        let dash = ascii_char(b'-');
        let colon = ascii_char(b':');

        let ParsedItem(input, year) = exactly_n_digits(4)(input).ok_or(InvalidComponent("year"))?;
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, month) =
            exactly_n_digits(2)(input).ok_or(InvalidComponent("month"))?;
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, day) = exactly_n_digits(2)(input).ok_or(InvalidComponent("day"))?;
        let input = ascii_char_ignore_case(b'T')(input)
            .ok_or(InvalidLiteral)?
            .unwrap();
        let ParsedItem(input, hour) = exactly_n_digits(2)(input).ok_or(InvalidComponent("hour"))?;
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, minute) =
            exactly_n_digits(2)(input).ok_or(InvalidComponent("minute"))?;
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, second) = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("second"))?
            .map(|seconds| if seconds == 60 { 59 } else { seconds });
        let ParsedItem(input, nanosecond) =
            if let Some(ParsedItem(input, ())) = ascii_char(b'.')(input) {
                let ParsedItem(mut input, mut value) = any_digit(input)
                    .ok_or(InvalidComponent("subsecond"))?
                    .map(|v| v as u32 * 100_000_000);

                let mut multiplier = 10_000_000;
                while let Some(ParsedItem(new_input, digit)) = any_digit(input) {
                    value += (digit - b'0') as u32 * multiplier;
                    input = new_input;
                    multiplier /= 10;
                }

                ParsedItem(input, value)
            } else {
                ParsedItem(input, 0)
            };
        let ParsedItem(input, offset) = {
            if let Some(ParsedItem(input, ())) = ascii_char_ignore_case(b'Z')(input) {
                ParsedItem(input, UtcOffset::UTC)
            } else {
                let ParsedItem(input, offset_sign) =
                    sign(input).ok_or(InvalidComponent("offset_hour"))?;
                let ParsedItem(input, offset_hour) =
                    exactly_n_digits::<i8>(2)(input).ok_or(InvalidComponent("offset_hour"))?;
                let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
                let ParsedItem(input, offset_minute) =
                    exactly_n_digits(2)(input).ok_or(InvalidComponent("offset_minute"))?;
                ParsedItem(
                    input,
                    UtcOffset::from_hms(
                        if offset_sign == b'-' {
                            -offset_hour
                        } else {
                            offset_hour
                        },
                        offset_minute,
                        0,
                    )
                    .map_err(TryFromParsed::ComponentRange)?,
                )
            }
        };

        if !input.is_empty() {
            return Err(error::Parse::UnexpectedTrailingCharacters);
        }

        Ok(Date::from_calendar_date(year, month, day)
            .map_err(TryFromParsed::ComponentRange)?
            .with_hms_nano(hour, minute, second, nanosecond)
            .map_err(TryFromParsed::ComponentRange)?
            .assume_offset(offset))
    }
}
<commit_msg>Eliminate unused associated type<commit_after>//! A trait that can be used to parse an item from an input.

#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::convert::TryInto;

use crate::error::TryFromParsed;
use crate::format_description::{well_known, FormatItem};
use crate::parsing::shim::SliceStripPrefix;
use crate::parsing::{Parsed, ParsedItem};
use crate::{error, Date, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};

/// Seal the trait to prevent downstream users from implementing it, while still allowing it to
/// exist in generic bounds.
pub(crate) mod sealed {

    #[allow(clippy::wildcard_imports)]
    use super::*;

    /// Parse the item using a format description and an input.
    #[cfg_attr(__time_03_docs, doc(cfg(feature = "parsing")))]
    pub trait Parsable {
        /// Parse the item into the provided [`Parsed`] struct.
        ///
        /// This method can be used to parse part of a type without parsing the full value.
        fn parse_into<'a>(
            &self,
            input: &'a [u8],
            parsed: &mut Parsed,
        ) -> Result<&'a [u8], error::Parse>;

        /// Parse the item into a new [`Parsed`] struct.
        ///
        /// This method can only be used to parse a complete value of a type. If any characters
        /// remain after parsing, an error will be returned.
        fn parse(&self, input: &[u8]) -> Result<Parsed, error::Parse> {
            let mut parsed = Parsed::new();
            if self.parse_into(input, &mut parsed)?.is_empty() {
                Ok(parsed)
            } else {
                Err(error::Parse::UnexpectedTrailingCharacters)
            }
        }

        /// Parse a [`Date`] from the format description.
        fn parse_date(&self, input: &[u8]) -> Result<Date, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`Time`] from the format description.
        fn parse_time(&self, input: &[u8]) -> Result<Time, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`UtcOffset`] from the format description.
        fn parse_offset(&self, input: &[u8]) -> Result<UtcOffset, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`PrimitiveDateTime`] from the format description.
        fn parse_date_time(&self, input: &[u8]) -> Result<PrimitiveDateTime, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }

        /// Parse a [`OffsetDateTime`] from the format description.
        fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> {
            Ok(self.parse(input)?.try_into()?)
        }
    }
}

impl sealed::Parsable for FormatItem<'_> {
    fn parse_into<'a>(
        &self,
        mut input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], error::Parse> {
        match self {
            Self::Literal(literal) => {
                input = input
                    .strip_prefix_(literal)
                    .ok_or(error::ParseFromDescription::InvalidLiteral)?;
            }
            Self::Component(component) => input = parsed.parse_component(input, *component)?,
            Self::Compound(compound) => input = compound.parse_into(input, parsed)?,
        }
        Ok(input)
    }
}

impl sealed::Parsable for &[FormatItem<'_>] {
    fn parse_into<'a>(
        &self,
        mut input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], error::Parse> {
        for item in self.iter() {
            input = item.parse_into(input, parsed)?;
        }
        Ok(input)
    }
}

#[cfg(feature = "alloc")]
#[cfg_attr(__time_03_docs, doc(cfg(feature = "alloc")))]
impl sealed::Parsable for Vec<FormatItem<'_>> {
    fn parse_into<'a>(
        &self,
        input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], error::Parse> {
        self.as_slice().parse_into(input, parsed)
    }
}

impl sealed::Parsable for well_known::Rfc3339 {
    fn parse_into<'a>(
        &self,
        input: &'a [u8],
        parsed: &mut Parsed,
    ) -> Result<&'a [u8], error::Parse> {
        use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral};
        use crate::parsing::combinator::{
            any_digit, ascii_char, ascii_char_ignore_case, exactly_n_digits, sign,
        };

        let dash = ascii_char(b'-');
        let colon = ascii_char(b':');

        let input = exactly_n_digits(4)(input)
            .ok_or(InvalidComponent("year"))?
            .assign_value_to_with(&mut parsed.year, |year: u32| year as i32);
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("month"))?
            .assign_value_to(&mut parsed.month);
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("day"))?
            .assign_value_to(&mut parsed.day);
        let input = ascii_char_ignore_case(b'T')(input)
            .ok_or(InvalidLiteral)?
            .unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("hour"))?
            .assign_value_to(&mut parsed.hour_24);
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("minute"))?
            .assign_value_to(&mut parsed.minute);
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("second"))?
            .assign_value_to_with(&mut parsed.second, |second| {
                // The RFC explicitly allows leap seconds. We don't support them, so treat it as
                // the previous second.
                if second == 60 { 59 } else { second }
            });
        let input = if let Some(ParsedItem(input, ())) = ascii_char(b'.')(input) {
            let ParsedItem(mut input, mut value) = any_digit(input)
                .ok_or(InvalidComponent("subsecond"))?
                .map(|v| v as u32 * 100_000_000);

            let mut multiplier = 10_000_000;
            while let Some(ParsedItem(new_input, digit)) = any_digit(input) {
                value += (digit - b'0') as u32 * multiplier;
                input = new_input;
                multiplier /= 10;
            }

            ParsedItem(input, value).assign_value_to(&mut parsed.subsecond)
        } else {
            input
        };

        if let Some(ParsedItem(input, ())) = ascii_char_ignore_case(b'Z')(input) {
            parsed.offset_hour = Some(0);
            parsed.offset_minute = Some(0);
            parsed.offset_second = Some(0);
            return Ok(input);
        }

        let ParsedItem(input, offset_sign) = sign(input).ok_or(InvalidComponent("offset_hour"))?;
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("offset_hour"))?
            .assign_value_to_with(&mut parsed.offset_hour, |offset_hour: u8| {
                if offset_sign == b'-' {
                    -(offset_hour as i8)
                } else {
                    offset_hour as _
                }
            });
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let input = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("offset_minute"))?
            .assign_value_to(&mut parsed.offset_minute);

        Ok(input)
    }

    fn parse_offset_date_time(&self, input: &[u8]) -> Result<OffsetDateTime, error::Parse> {
        use crate::error::ParseFromDescription::{InvalidComponent, InvalidLiteral};
        use crate::parsing::combinator::{
            any_digit, ascii_char, ascii_char_ignore_case, exactly_n_digits, sign,
        };

        let dash = ascii_char(b'-');
        let colon = ascii_char(b':');

        let ParsedItem(input, year) = exactly_n_digits(4)(input).ok_or(InvalidComponent("year"))?;
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, month) =
            exactly_n_digits(2)(input).ok_or(InvalidComponent("month"))?;
        let input = dash(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, day) = exactly_n_digits(2)(input).ok_or(InvalidComponent("day"))?;
        let input = ascii_char_ignore_case(b'T')(input)
            .ok_or(InvalidLiteral)?
            .unwrap();
        let ParsedItem(input, hour) = exactly_n_digits(2)(input).ok_or(InvalidComponent("hour"))?;
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, minute) =
            exactly_n_digits(2)(input).ok_or(InvalidComponent("minute"))?;
        let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
        let ParsedItem(input, second) = exactly_n_digits(2)(input)
            .ok_or(InvalidComponent("second"))?
            .map(|seconds| if seconds == 60 { 59 } else { seconds });
        let ParsedItem(input, nanosecond) =
            if let Some(ParsedItem(input, ())) = ascii_char(b'.')(input) {
                let ParsedItem(mut input, mut value) = any_digit(input)
                    .ok_or(InvalidComponent("subsecond"))?
                    .map(|v| v as u32 * 100_000_000);

                let mut multiplier = 10_000_000;
                while let Some(ParsedItem(new_input, digit)) = any_digit(input) {
                    value += (digit - b'0') as u32 * multiplier;
                    input = new_input;
                    multiplier /= 10;
                }

                ParsedItem(input, value)
            } else {
                ParsedItem(input, 0)
            };
        let ParsedItem(input, offset) = {
            if let Some(ParsedItem(input, ())) = ascii_char_ignore_case(b'Z')(input) {
                ParsedItem(input, UtcOffset::UTC)
            } else {
                let ParsedItem(input, offset_sign) =
                    sign(input).ok_or(InvalidComponent("offset_hour"))?;
                let ParsedItem(input, offset_hour) =
                    exactly_n_digits::<i8>(2)(input).ok_or(InvalidComponent("offset_hour"))?;
                let input = colon(input).ok_or(InvalidLiteral)?.unwrap();
                let ParsedItem(input, offset_minute) =
                    exactly_n_digits(2)(input).ok_or(InvalidComponent("offset_minute"))?;
                ParsedItem(
                    input,
                    UtcOffset::from_hms(
                        if offset_sign == b'-' {
                            -offset_hour
                        } else {
                            offset_hour
                        },
                        offset_minute,
                        0,
                    )
                    .map_err(TryFromParsed::ComponentRange)?,
                )
            }
        };

        if !input.is_empty() {
            return Err(error::Parse::UnexpectedTrailingCharacters);
        }

        Ok(Date::from_calendar_date(year, month, day)
            .map_err(TryFromParsed::ComponentRange)?
            .with_hms_nano(hour, minute, second, nanosecond)
            .map_err(TryFromParsed::ComponentRange)?
            .assume_offset(offset))
    }
}
<|endoftext|>


<commit_before>use app;
use app::App;
use OptionLoaned;
use graphics::Sprite;
use math::Transform;
use component::Component;
use component::ComponentAny;
use component::Message;
use std::collections::BTreeMap;
use std::mem::replace;
use nphysics2d::object::{RigidBody, RigidBodyHandle};
use nphysics2d::math::Matrix;
use nalgebra::{Rotation2, Vector2, Vector1, Rotation};

pub struct GameObject {
    pub transform: Transform,
    pub sprite: Option<Sprite>,
    pub body: Option<RigidBodyHandle<f32>>,
    // This value will never be 0.  0 can now be used as a null value.
    id: u64,
    components: BTreeMap<i32, Option<Box<ComponentAny>>>,
    drop: bool,
}

impl GameObject {
    pub fn id(&self) -> u64 {
        self.id
    }

    pub fn drop(&mut self) {
        self.drop = true;
    }

    pub fn send_message_to_component(&mut self,
                                     app: &mut App,
                                     message: &Message,
                                     component_id: i32) {
        let mut component_option = None;
        if let Some(component_ref) = self.components.get_mut(&component_id) {
            component_option = replace(component_ref, None);
        }
        if let Some(ref mut component) = component_option {
            component.receive_message(app, self, &message);
        }
        if let Some(component_ref) = self.components.get_mut(&component_id) {
            replace(component_ref, component_option);
        }
    }

    pub fn receive_message(&mut self, app: &mut App, message: &Message) {
        for key in self.components
                .keys()
                .map(|x| *x)
                .collect::<Vec<i32>>() {
            self.send_message_to_component(app, message, key);
        }
    }

    pub fn update(&mut self, app: &mut App, delta_time: f32) {
        let message = &Message::Update { delta_time: delta_time };
        self.receive_message(app, message)
    }

    pub fn component_keys<'a>(&'a self) -> Box<Iterator<Item = i32> + 'a> {
        Box::new(self.components.keys().map(|x| *x))
    }

    pub fn component_keys_with_type<'a, T>(&'a self) -> Box<Iterator<Item = i32> + 'a>
        where T: Component + 'static
    {
        Box::new(self.components.iter().filter_map(|(k, c)| if let &Some(ref c) = c {
                                                       if c.as_any().is::<T>() {
                                                           Some(*k)
                                                       } else {
                                                           None
                                                       }
                                                   } else {
                                                       None
                                                   }))
    }

    pub fn remove_component(&mut self,
                            app: &mut App,
                            index: i32)
                            -> OptionLoaned<Box<ComponentAny>> {
        let mut component_result = self.components.remove(&index);
        if let Some(Some(ref mut component)) = component_result {
            component.receive_message(app, self, &Message::OnDetach);
        }
        OptionLoaned::from(component_result)
    }

    pub fn component(&self, index: i32) -> OptionLoaned<&Box<ComponentAny>> {
        OptionLoaned::from(self.components.get(&index))
    }

    pub fn component_mut(&mut self, index: i32) -> OptionLoaned<&mut Box<ComponentAny>> {
        OptionLoaned::from(self.components.get_mut(&index))
    }

    pub fn component_with_type<T>(&self, index: i32) -> Option<&T>
        where T: Component + 'static
    {
        if let Some(&Some(ref component)) = self.components.get(&index) {
            return component.as_any().downcast_ref::<T>();
        }
        None
    }

    pub fn component_mut_with_type<T>(&mut self, index: i32) -> Option<&mut T>
        where T: Component + 'static
    {
        if let Some(&mut Some(ref mut component)) = self.components.get_mut(&index) {
            return component.as_any_mut().downcast_mut::<T>();
        }
        None
    }

    pub fn insert_component<T>(&mut self,
                               app: &mut App,
                               component: T,
                               index: i32)
                               -> Option<Box<ComponentAny>>
        where T: Component + 'static
    {
        let mut boxxed = Box::new(component);
        boxxed.receive_message(app, self, &Message::Start { key: index });
        let replaced = self.components.insert(index, Some(boxxed));
        if let Some(Some(component)) = replaced {
            Some(component)
        } else {
            None
        }
    }

    pub fn add_component<T>(&mut self, app: &mut App, component: T) -> i32
        where T: Component + 'static
    {
        let new_key = self.components
            .keys()
            .map(|x| *x)
            .nth(0)
            .unwrap_or(1) - 1;
        self.insert_component(app, component, new_key);
        new_key
    }

    pub fn set_rigid_body(&mut self, app: &mut App, rigid_body: RigidBody<f32>) {
        self.body = Some(app.world.add_rigid_body(rigid_body));
    }
}

pub fn new(app: &mut App) -> GameObject {
    GameObject {
        id: app::next_game_object_id(app),
        drop: false,
        transform: Transform::new(),
        components: BTreeMap::new(),
        sprite: None,
        body: None,
    }
}

pub fn was_dropped(game_object: &GameObject) -> bool {
    game_object.drop
}

pub fn copy_from_physics(game_object: &mut GameObject) {
    if let &Some(ref body_box) = &game_object.body {
        let body_borrow = body_box.borrow();
        *game_object.transform.mut_x() = body_borrow.position().translation.x;
        *game_object.transform.mut_y() = body_borrow.position().translation.y;
        *game_object.transform.mut_rotation() = body_borrow.position()
            .rotation
            .rotation()
            .x;
    }
}

pub fn copy_to_physics(game_object: &mut GameObject) {
    if let Some(ref mut body_box) = game_object.body {
        body_box.borrow_mut()
            .set_transformation(Matrix::<f32> {
                                    rotation: Rotation2::new(Vector1 {
                                                                 x: *game_object.transform
                                                                         .rotation(),
                                                             }),
                                    translation: Vector2 {
                                        x: *game_object.transform.x(),
                                        y: *game_object.transform.y(),
                                    },
                                });
    }
}
<commit_msg>Improve GameObject documentation<commit_after>use app;
use app::App;
use OptionLoaned;
use graphics::Sprite;
use math::Transform;
use component::Component;
use component::ComponentAny;
use component::Message;
use std::collections::BTreeMap;
use std::mem::replace;
use nphysics2d::object::{RigidBody, RigidBodyHandle};
use nphysics2d::math::Matrix;
use nalgebra::{Rotation2, Vector2, Vector1, Rotation};

/// GameObjects are the primary descriptor for things that are visible in the game world.
/// Players, items, enemies, and whatever else exists in your game world are typically GameObjects.
///
/// To create a new GameObject use nitro::App::new_gameobject().
pub struct GameObject {
    pub transform: Transform,
    pub sprite: Option<Sprite>,
    pub body: Option<RigidBodyHandle<f32>>,
    // This value will never be 0.  0 can now be used as a null value.
    id: u64,
    components: BTreeMap<i32, Option<Box<ComponentAny>>>,
    drop: bool,
}

impl GameObject {
    pub fn id(&self) -> u64 {
        self.id
    }

    pub fn drop(&mut self) {
        self.drop = true;
    }

    pub fn send_message_to_component(&mut self,
                                     app: &mut App,
                                     message: &Message,
                                     component_id: i32) {
        let mut component_option = None;
        if let Some(component_ref) = self.components.get_mut(&component_id) {
            component_option = replace(component_ref, None);
        }
        if let Some(ref mut component) = component_option {
            component.receive_message(app, self, &message);
        }
        if let Some(component_ref) = self.components.get_mut(&component_id) {
            replace(component_ref, component_option);
        }
    }

    pub fn receive_message(&mut self, app: &mut App, message: &Message) {
        for key in self.components
                .keys()
                .map(|x| *x)
                .collect::<Vec<i32>>() {
            self.send_message_to_component(app, message, key);
        }
    }

    pub fn update(&mut self, app: &mut App, delta_time: f32) {
        let message = &Message::Update { delta_time: delta_time };
        self.receive_message(app, message)
    }

    pub fn component_keys<'a>(&'a self) -> Box<Iterator<Item = i32> + 'a> {
        Box::new(self.components.keys().map(|x| *x))
    }

    pub fn component_keys_with_type<'a, T>(&'a self) -> Box<Iterator<Item = i32> + 'a>
        where T: Component + 'static
    {
        Box::new(self.components.iter().filter_map(|(k, c)| if let &Some(ref c) = c {
                                                       if c.as_any().is::<T>() {
                                                           Some(*k)
                                                       } else {
                                                           None
                                                       }
                                                   } else {
                                                       None
                                                   }))
    }

    pub fn remove_component(&mut self,
                            app: &mut App,
                            index: i32)
                            -> OptionLoaned<Box<ComponentAny>> {
        let mut component_result = self.components.remove(&index);
        if let Some(Some(ref mut component)) = component_result {
            component.receive_message(app, self, &Message::OnDetach);
        }
        OptionLoaned::from(component_result)
    }

    pub fn component(&self, index: i32) -> OptionLoaned<&Box<ComponentAny>> {
        OptionLoaned::from(self.components.get(&index))
    }

    pub fn component_mut(&mut self, index: i32) -> OptionLoaned<&mut Box<ComponentAny>> {
        OptionLoaned::from(self.components.get_mut(&index))
    }

    pub fn component_with_type<T>(&self, index: i32) -> Option<&T>
        where T: Component + 'static
    {
        if let Some(&Some(ref component)) = self.components.get(&index) {
            return component.as_any().downcast_ref::<T>();
        }
        None
    }

    pub fn component_mut_with_type<T>(&mut self, index: i32) -> Option<&mut T>
        where T: Component + 'static
    {
        if let Some(&mut Some(ref mut component)) = self.components.get_mut(&index) {
            return component.as_any_mut().downcast_mut::<T>();
        }
        None
    }

    pub fn insert_component<T>(&mut self,
                               app: &mut App,
                               component: T,
                               index: i32)
                               -> Option<Box<ComponentAny>>
        where T: Component + 'static
    {
        let mut boxxed = Box::new(component);
        boxxed.receive_message(app, self, &Message::Start { key: index });
        let replaced = self.components.insert(index, Some(boxxed));
        if let Some(Some(component)) = replaced {
            Some(component)
        } else {
            None
        }
    }

    pub fn add_component<T>(&mut self, app: &mut App, component: T) -> i32
        where T: Component + 'static
    {
        let new_key = self.components
            .keys()
            .map(|x| *x)
            .nth(0)
            .unwrap_or(1) - 1;
        self.insert_component(app, component, new_key);
        new_key
    }

    pub fn set_rigid_body(&mut self, app: &mut App, rigid_body: RigidBody<f32>) {
        self.body = Some(app.world.add_rigid_body(rigid_body));
    }
}

pub fn new(app: &mut App) -> GameObject {
    GameObject {
        id: app::next_game_object_id(app),
        drop: false,
        transform: Transform::new(),
        components: BTreeMap::new(),
        sprite: None,
        body: None,
    }
}

pub fn was_dropped(game_object: &GameObject) -> bool {
    game_object.drop
}

pub fn copy_from_physics(game_object: &mut GameObject) {
    if let &Some(ref body_box) = &game_object.body {
        let body_borrow = body_box.borrow();
        *game_object.transform.mut_x() = body_borrow.position().translation.x;
        *game_object.transform.mut_y() = body_borrow.position().translation.y;
        *game_object.transform.mut_rotation() = body_borrow.position()
            .rotation
            .rotation()
            .x;
    }
}

pub fn copy_to_physics(game_object: &mut GameObject) {
    if let Some(ref mut body_box) = game_object.body {
        body_box.borrow_mut()
            .set_transformation(Matrix::<f32> {
                                    rotation: Rotation2::new(Vector1 {
                                                                 x: *game_object.transform
                                                                         .rotation(),
                                                             }),
                                    translation: Vector2 {
                                        x: *game_object.transform.x(),
                                        y: *game_object.transform.y(),
                                    },
                                });
    }
}
<|endoftext|>


<commit_before>//! Game window operations.

use input::InputEvent;

/// Settings for window behavior.
pub struct GameWindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window
    pub size: [u32, ..2],
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl GameWindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> GameWindowSettings {
        GameWindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Implemented by window back-end.
pub trait GameWindow {
    /// Get the window's settings.
    fn get_settings<'a>(&'a self) -> &'a GameWindowSettings;

    /// Returns ture if the window should close.
    fn should_close(&self) -> bool;

    /// Inform the window that it should close.
    fn close(&mut self);

    /// Get the window's size
    fn get_size(&self) -> (u32, u32) {
        (self.get_settings().size[0], self.get_settings().size[1])
    }

    /// Get the size in drawing coordinates.
    fn get_draw_size(&self) -> (u32, u32) {
        self.get_size()
    }

    /// Swap buffers.
    fn swap_buffers(&self) {}

    /// When the cursor is captured,
    /// it is hidden and the cursor position does not change.
    /// Only relative mouse motion is registered.
    fn capture_cursor(&mut self, _enabled: bool) {}

    /// Poll a event from window's event queue.
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

<commit_msg>Added NoGameWindow, for those who want to run a windowless gameloop<commit_after>//! Game window operations.

use input::InputEvent;

/// Settings for window behavior.
pub struct GameWindowSettings {
    /// Title of the window.
    pub title: String,
    /// The size of the window
    pub size: [u32, ..2],
    /// If true, the window is fullscreen.
    pub fullscreen: bool,
    /// If true, exit when pressing Esc.
    pub exit_on_esc: bool,
}

impl GameWindowSettings {
    /// Gets default settings.
    ///
    /// This exits the window when pressing `Esc`.
    /// The background color is set to black.
    pub fn default() -> GameWindowSettings {
        GameWindowSettings {
            title: "Piston".to_string(),
            size: [640, 480],
            fullscreen: false,
            exit_on_esc: true,
        }
    }
}

/// Implemented by window back-end.
pub trait GameWindow {
    /// Get the window's settings.
    fn get_settings<'a>(&'a self) -> &'a GameWindowSettings;

    /// Returns true if the window should close.
    fn should_close(&self) -> bool;

    /// Inform the window that it should close.
    fn close(&mut self);

    /// Get the window's size
    fn get_size(&self) -> (u32, u32) {
        (self.get_settings().size[0], self.get_settings().size[1])
    }

    /// Get the size in drawing coordinates.
    fn get_draw_size(&self) -> (u32, u32) {
        self.get_size()
    }

    /// Swap buffers.
    fn swap_buffers(&self) {}

    /// When the cursor is captured,
    /// it is hidden and the cursor position does not change.
    /// Only relative mouse motion is registered.
    fn capture_cursor(&mut self, _enabled: bool) {}

    /// Poll a event from window's event queue.
    fn poll_event(&mut self) -> Option<InputEvent> { None }
}

/// An implementation of GameWindow that represents running without a window at all
pub struct NoGameWindow {
    settings: GameWindowSettings
}

impl NoGameWindow {
    /// Create a new nonexistant game window
    pub fn new(settings: GameWindowSettings) -> NoGameWindow {
         NoGameWindow {
             settings: settings
         }
    }
}

impl GameWindow for NoGameWindow {
     fn get_settings<'a>(&'a self) -> &'a GameWindowSettings {
        &self.settings
     }

    fn should_close(&self) -> bool {
        false
    }

    fn close(&mut self) {
        // One can't close a window that doesn't exist!
        ()
    }

    fn get_size(&self) -> (u32, u32) {
        (0, 0)
    }
}
<|endoftext|>


<commit_before>//! Glyph caching

use { freetype, graphics, Texture, TextureSettings };
use std::collections::HashMap;
use graphics::types::Scalar;

use std::path::Path;
use error::Error;

pub use graphics::types::FontSize;

/// The type alias for font characters.
pub type Character<'a> = graphics::character::Character<'a, Texture>;

/// A struct used for caching rendered font.
pub struct GlyphCache<'a> {
    /// The font face.
    pub face: freetype::Face<'a>,
    // Maps from fontsize and character to offset, size and texture.
    data: HashMap<(FontSize, char), ([Scalar; 2], [Scalar; 2], Texture)>,
}

impl<'a> GlyphCache<'a> {
    /// Constructor for a GlyphCache.
    pub fn new(font: &Path) -> Result<GlyphCache<'static>, Error> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        let face = match freetype.new_face(font, 0) {
            Ok(face) => face,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new(),
        })
    }

    /// Creates a GlyphCache for a font stored in memory.
    pub fn from_bytes(font: &'a [u8]) -> Result<GlyphCache<'a>, Error> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(Error::FreetypeError(why))
        };
        let face = match freetype.new_memory_face(font, 0) {
            Ok(face) => face,
            Err(why) => return Err(Error::FreetypeError(why))
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new()
        })
    }

    /// Load a `Character` from a given `FontSize` and `char`.
    fn load_character(&mut self, size: FontSize, ch: char) {
        // Don't load glyph twice.
        if !self.data.contains_key(&(size, ch)) {
            return;
        }

        self.face.set_pixel_sizes(0, size).unwrap();
        self.face.load_char(ch as usize, freetype::face::DEFAULT).unwrap();
        let glyph = self.face.glyph().get_glyph().unwrap();
        let bitmap_glyph = glyph.to_bitmap(freetype::render_mode::RenderMode::Normal, None)
            .unwrap();
        let bitmap = bitmap_glyph.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32,
                                                 &TextureSettings::new()).unwrap();
        self.data.insert((size, ch), (
            [bitmap_glyph.left() as f64, bitmap_glyph.top() as f64],
            [(glyph.advance_x() >> 16) as f64, (glyph.advance_y() >> 16) as f64],
            texture,
        ));
    }

    /// Load all characters in the `chars` iterator for `size`
    pub fn preload_chars<I>(
        &mut self,
        size: FontSize,
        chars: I
    )
        where
            I: Iterator<Item = char>
    {
        for ch in chars {
            self.load_character(size, ch);
        }
    }

    /// Load all the printable ASCII characters for `size`. Includes space.
    pub fn preload_printable_ascii(&mut self, size: FontSize) {
        // [0x20, 0x7F) contains all printable ASCII characters ([' ', '~'])
        self.preload_chars(size, (0x20u8 .. 0x7F).map(|ch| ch as char));
    }

    /// Return `ch` for `size` if it's already cached. Don't load.
    /// See the `preload_*` functions.
    pub fn opt_character(&self, size: FontSize, ch: char) -> Option<Character> {
        self.data.get(&(size, ch)).map(|&(offset, size, ref texture)| {
            Character {
                offset: offset,
                size: size,
                texture: texture
            }
        })
    }
}

impl<'b> graphics::character::CharacterCache for GlyphCache<'b> {
    type Texture = Texture;

    fn character<'a>(&'a mut self, size: FontSize, ch: char) -> Character<'a> {
        if !self.data.contains_key(&(size, ch)) {
            self.load_character(size, ch);
        }
        let &(offset, size, ref texture) = &self.data[&(size, ch)];
        return Character {
            offset: offset,
            size: size,
            texture: texture
        }
    }
}
<commit_msg>Fix inverted condition in `GlyphCache.load_character()`<commit_after>//! Glyph caching

use { freetype, graphics, Texture, TextureSettings };
use std::collections::HashMap;
use graphics::types::Scalar;

use std::path::Path;
use error::Error;

pub use graphics::types::FontSize;

/// The type alias for font characters.
pub type Character<'a> = graphics::character::Character<'a, Texture>;

/// A struct used for caching rendered font.
pub struct GlyphCache<'a> {
    /// The font face.
    pub face: freetype::Face<'a>,
    // Maps from fontsize and character to offset, size and texture.
    data: HashMap<(FontSize, char), ([Scalar; 2], [Scalar; 2], Texture)>,
}

impl<'a> GlyphCache<'a> {
    /// Constructor for a GlyphCache.
    pub fn new(font: &Path) -> Result<GlyphCache<'static>, Error> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        let face = match freetype.new_face(font, 0) {
            Ok(face) => face,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new(),
        })
    }

    /// Creates a GlyphCache for a font stored in memory.
    pub fn from_bytes(font: &'a [u8]) -> Result<GlyphCache<'a>, Error> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(Error::FreetypeError(why))
        };
        let face = match freetype.new_memory_face(font, 0) {
            Ok(face) => face,
            Err(why) => return Err(Error::FreetypeError(why))
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new()
        })
    }

    /// Load a `Character` from a given `FontSize` and `char`.
    fn load_character(&mut self, size: FontSize, ch: char) {
        // Don't load glyph twice.
        if self.data.contains_key(&(size, ch)) {
            return;
        }

        self.face.set_pixel_sizes(0, size).unwrap();
        self.face.load_char(ch as usize, freetype::face::DEFAULT).unwrap();
        let glyph = self.face.glyph().get_glyph().unwrap();
        let bitmap_glyph = glyph.to_bitmap(freetype::render_mode::RenderMode::Normal, None)
            .unwrap();
        let bitmap = bitmap_glyph.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32,
                                                 &TextureSettings::new()).unwrap();
        self.data.insert((size, ch), (
            [bitmap_glyph.left() as f64, bitmap_glyph.top() as f64],
            [(glyph.advance_x() >> 16) as f64, (glyph.advance_y() >> 16) as f64],
            texture,
        ));
    }

    /// Load all characters in the `chars` iterator for `size`
    pub fn preload_chars<I>(
        &mut self,
        size: FontSize,
        chars: I
    )
        where
            I: Iterator<Item = char>
    {
        for ch in chars {
            self.load_character(size, ch);
        }
    }

    /// Load all the printable ASCII characters for `size`. Includes space.
    pub fn preload_printable_ascii(&mut self, size: FontSize) {
        // [0x20, 0x7F) contains all printable ASCII characters ([' ', '~'])
        self.preload_chars(size, (0x20u8 .. 0x7F).map(|ch| ch as char));
    }

    /// Return `ch` for `size` if it's already cached. Don't load.
    /// See the `preload_*` functions.
    pub fn opt_character(&self, size: FontSize, ch: char) -> Option<Character> {
        self.data.get(&(size, ch)).map(|&(offset, size, ref texture)| {
            Character {
                offset: offset,
                size: size,
                texture: texture
            }
        })
    }
}

impl<'b> graphics::character::CharacterCache for GlyphCache<'b> {
    type Texture = Texture;

    fn character<'a>(&'a mut self, size: FontSize, ch: char) -> Character<'a> {
        if !self.data.contains_key(&(size, ch)) {
            self.load_character(size, ch);
        }
        let &(offset, size, ref texture) = &self.data[&(size, ch)];
        return Character {
            offset: offset,
            size: size,
            texture: texture
        }
    }
}
<|endoftext|>


<commit_before>use std::ffi::c_void;
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::sync::Arc;

use neon_runtime::reference;
#[cfg(feature = "napi-6")]
use neon_runtime::tsfn::ThreadsafeFunction;

use crate::context::Context;
use crate::handle::Handle;
#[cfg(feature = "napi-6")]
use crate::lifecycle::InstanceData;
use crate::object::Object;
use crate::types::boxed::Finalize;

#[repr(transparent)]
#[derive(Clone)]
pub(crate) struct NapiRef(*mut c_void);

// # Safety
// `NapiRef` are reference counted types that allow references to JavaScript objects
// to outlive a `Context` (`napi_env`). Since access is serialized by obtaining a
// `Context`, they are both `Send` and `Sync`.
// https://nodejs.org/api/n-api.html#n_api_references_to_objects_with_a_lifespan_longer_than_that_of_the_native_method
unsafe impl Send for NapiRef {}
unsafe impl Sync for NapiRef {}

/// A thread-safe handle that holds a reference to a JavaScript object and
/// prevents it from being garbage collected.
///
/// A `Root<T>` may be sent across threads, but the referenced object may
/// only be accessed on the JavaScript thread that created it.
pub struct Root<T> {
    internal: NapiRef,
    #[cfg(feature = "napi-6")]
    drop_queue: Arc<ThreadsafeFunction<NapiRef>>,
    _phantom: PhantomData<T>,
}

impl<T> std::fmt::Debug for Root<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Root<{}>", std::any::type_name::<T>())
    }
}

// `Root` are intended to be `Send` and `Sync`
// Safety: `Root` contains two types. A `NapiRef` which is `Send` and `Sync` and a
// `PhantomData` that does not impact the safety.
unsafe impl<T> Send for Root<T> {}
unsafe impl<T> Sync for Root<T> {}

impl<T: Object> Root<T> {
    /// Create a reference to a JavaScript object. The object will not be
    /// garbage collected until the `Root` is dropped. A `Root<T>` may only
    /// be dropped on the JavaScript thread that created it.
    ///
    /// The caller _should_ ensure `Root::into_inner` or `Root::drop` is called
    /// to properly dispose of the `Root<T>`. If the value is dropped without
    /// calling one of these methods:
    /// * N-API < 6, Neon will `panic` to notify of the leak
    /// * N-API >= 6, Neon will drop from a global queue at a runtime cost
    pub fn new<'a, C: Context<'a>>(cx: &mut C, value: &T) -> Self {
        let env = cx.env().to_raw();
        let internal = unsafe { reference::new(env, value.to_raw()) };

        Self {
            internal: NapiRef(internal as *mut _),
            #[cfg(feature = "napi-6")]
            drop_queue: InstanceData::drop_queue(cx),
            _phantom: PhantomData,
        }
    }

    /// Clone a reference to the contained JavaScript object. This method can
    /// be considered identical to the following:
    /// ```
    /// # use neon::prelude::*;
    /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult<JsUndefined> {
    /// # let root = cx.argument::<JsObject>(0)?.root(&mut cx);
    /// let inner = root.into_inner(&mut cx);
    /// let cloned = inner.root(&mut cx);
    /// let root = inner.root(&mut cx);
    /// # Ok(cx.undefined())
    /// # }
    /// ```
    pub fn clone<'a, C: Context<'a>>(&self, cx: &mut C) -> Self {
        let env = cx.env();
        let internal = self.internal.0 as *mut _;

        unsafe {
            reference::reference(env.to_raw(), internal);
        };

        Self {
            internal: self.internal.clone(),
            #[cfg(feature = "napi-6")]
            drop_queue: Arc::clone(&self.drop_queue),
            _phantom: PhantomData,
        }
    }

    /// Safely drop a `Root<T>` without returning the referenced JavaScript
    /// object.
    pub fn drop<'a, C: Context<'a>>(self, cx: &mut C) {
        let env = cx.env().to_raw();
        let internal = ManuallyDrop::new(self).internal.0 as *mut _;

        unsafe {
            reference::unreference(env, internal);
        }
    }

    /// Return the referenced JavaScript object and allow it to be garbage collected
    pub fn into_inner<'a, C: Context<'a>>(self, cx: &mut C) -> Handle<'a, T> {
        let env = cx.env();
        let internal = ManuallyDrop::new(self).internal.0 as *mut _;

        let local = unsafe { reference::get(env.to_raw(), internal) };

        unsafe {
            reference::unreference(env.to_raw(), internal);
        }

        Handle::new_internal(T::from_raw(env, local))
    }

    /// Access the inner JavaScript object without consuming the `Root`
    /// This method aliases the reference without changing the reference count. It
    /// can be used in place of a clone immediately followed by a call to `into_inner`.
    pub fn to_inner<'a, C: Context<'a>>(&self, cx: &mut C) -> Handle<'a, T> {
        let env = cx.env();
        let local = unsafe { reference::get(env.to_raw(), self.internal.0 as *mut _) };

        Handle::new_internal(T::from_raw(env, local))
    }
}

// Allows putting `Root<T>` directly in a container that implements `Finalize`
// For example, `Vec<Root<T>>` or `JsBox`.
impl<T: Object> Finalize for Root<T> {
    fn finalize<'a, C: Context<'a>>(self, cx: &mut C) {
        self.drop(cx);
    }
}

impl<T> Drop for Root<T> {
    #[cfg(not(feature = "napi-6"))]
    fn drop(&mut self) {
        // Destructors are called during stack unwinding, prevent a double
        // panic and instead prefer to leak.
        if std::thread::panicking() {
            eprintln!("Warning: neon::sync::Root leaked during a panic");
            return;
        }

        // Only panic if the event loop is still running
        if let Ok(true) = crate::context::internal::IS_RUNNING.try_with(|v| *v.borrow()) {
            panic!(
                "Must call `into_inner` or `drop` on `Root` \
                https://docs.rs/neon/latest/neon/sync/index.html#drop-safety"
            );
        }
    }

    #[cfg(feature = "napi-6")]
    fn drop(&mut self) {
        let _ = self.drop_queue.call(self.internal.clone(), None);
    }
}
<commit_msg>fix(neon): Fix a leak from global event queue Arc not being dropped<commit_after>use std::ffi::c_void;
use std::marker::PhantomData;
#[cfg(feature = "napi-6")]
use std::sync::Arc;

use neon_runtime::reference;
#[cfg(feature = "napi-6")]
use neon_runtime::tsfn::ThreadsafeFunction;

use crate::context::Context;
use crate::handle::Handle;
#[cfg(feature = "napi-6")]
use crate::lifecycle::InstanceData;
use crate::object::Object;
use crate::types::boxed::Finalize;

#[repr(transparent)]
#[derive(Clone)]
pub(crate) struct NapiRef(*mut c_void);

// # Safety
// `NapiRef` are reference counted types that allow references to JavaScript objects
// to outlive a `Context` (`napi_env`). Since access is serialized by obtaining a
// `Context`, they are both `Send` and `Sync`.
// https://nodejs.org/api/n-api.html#n_api_references_to_objects_with_a_lifespan_longer_than_that_of_the_native_method
unsafe impl Send for NapiRef {}
unsafe impl Sync for NapiRef {}

/// A thread-safe handle that holds a reference to a JavaScript object and
/// prevents it from being garbage collected.
///
/// A `Root<T>` may be sent across threads, but the referenced object may
/// only be accessed on the JavaScript thread that created it.
pub struct Root<T> {
    // `Option` is used to skip `Drop` when `Root::drop` or `Root::into_inner` is used.
    // It will *always* be `Some` when a user is interacting with `Root`.
    internal: Option<NapiRef>,
    #[cfg(feature = "napi-6")]
    drop_queue: Arc<ThreadsafeFunction<NapiRef>>,
    _phantom: PhantomData<T>,
}

impl<T> std::fmt::Debug for Root<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Root<{}>", std::any::type_name::<T>())
    }
}

// `Root` are intended to be `Send` and `Sync`
// Safety: `Root` contains two types. A `NapiRef` which is `Send` and `Sync` and a
// `PhantomData` that does not impact the safety.
unsafe impl<T> Send for Root<T> {}
unsafe impl<T> Sync for Root<T> {}

impl<T: Object> Root<T> {
    /// Create a reference to a JavaScript object. The object will not be
    /// garbage collected until the `Root` is dropped. A `Root<T>` may only
    /// be dropped on the JavaScript thread that created it.
    ///
    /// The caller _should_ ensure `Root::into_inner` or `Root::drop` is called
    /// to properly dispose of the `Root<T>`. If the value is dropped without
    /// calling one of these methods:
    /// * N-API < 6, Neon will `panic` to notify of the leak
    /// * N-API >= 6, Neon will drop from a global queue at a runtime cost
    pub fn new<'a, C: Context<'a>>(cx: &mut C, value: &T) -> Self {
        let env = cx.env().to_raw();
        let internal = unsafe { reference::new(env, value.to_raw()) };

        Self {
            internal: Some(NapiRef(internal as *mut _)),
            #[cfg(feature = "napi-6")]
            drop_queue: InstanceData::drop_queue(cx),
            _phantom: PhantomData,
        }
    }

    /// Clone a reference to the contained JavaScript object. This method can
    /// be considered identical to the following:
    /// ```
    /// # use neon::prelude::*;
    /// # fn my_neon_function(mut cx: FunctionContext) -> JsResult<JsUndefined> {
    /// # let root = cx.argument::<JsObject>(0)?.root(&mut cx);
    /// let inner = root.into_inner(&mut cx);
    /// let cloned = inner.root(&mut cx);
    /// let root = inner.root(&mut cx);
    /// # Ok(cx.undefined())
    /// # }
    /// ```
    pub fn clone<'a, C: Context<'a>>(&self, cx: &mut C) -> Self {
        let env = cx.env();
        let internal = self.as_napi_ref().0 as *mut _;

        unsafe {
            reference::reference(env.to_raw(), internal);
        };

        Self {
            internal: self.internal.clone(),
            #[cfg(feature = "napi-6")]
            drop_queue: Arc::clone(&self.drop_queue),
            _phantom: PhantomData,
        }
    }

    /// Safely drop a `Root<T>` without returning the referenced JavaScript
    /// object.
    pub fn drop<'a, C: Context<'a>>(self, cx: &mut C) {
        let env = cx.env().to_raw();
        let internal = self.into_napi_ref().0 as *mut _;

        unsafe {
            reference::unreference(env, internal);
        }
    }

    /// Return the referenced JavaScript object and allow it to be garbage collected
    pub fn into_inner<'a, C: Context<'a>>(self, cx: &mut C) -> Handle<'a, T> {
        let env = cx.env();
        let internal = self.into_napi_ref().0 as *mut _;

        let local = unsafe { reference::get(env.to_raw(), internal) };

        unsafe {
            reference::unreference(env.to_raw(), internal);
        }

        Handle::new_internal(T::from_raw(env, local))
    }

    /// Access the inner JavaScript object without consuming the `Root`
    /// This method aliases the reference without changing the reference count. It
    /// can be used in place of a clone immediately followed by a call to `into_inner`.
    pub fn to_inner<'a, C: Context<'a>>(&self, cx: &mut C) -> Handle<'a, T> {
        let env = cx.env();
        let local = unsafe { reference::get(env.to_raw(), self.as_napi_ref().0 as *mut _) };

        Handle::new_internal(T::from_raw(env, local))
    }

    fn as_napi_ref(&self) -> &NapiRef {
        self.internal
            .as_ref()
            // `unwrap` will not `panic` because `internal` will always be `Some`
            // until the `Root` is consumed.
            .unwrap()
    }

    fn into_napi_ref(mut self) -> NapiRef {
        self.internal
            .take()
            // `unwrap` will not `panic` because this is the only method place
            // `internal` is replaced with `None` and it consumes `self`.
            .unwrap()
    }
}

// Allows putting `Root<T>` directly in a container that implements `Finalize`
// For example, `Vec<Root<T>>` or `JsBox`.
impl<T: Object> Finalize for Root<T> {
    fn finalize<'a, C: Context<'a>>(self, cx: &mut C) {
        self.drop(cx);
    }
}

impl<T> Drop for Root<T> {
    #[cfg(not(feature = "napi-6"))]
    fn drop(&mut self) {
        // If `None`, the `NapiRef` has already been manually dropped
        if self.internal.is_none() {
            return;
        }

        // Destructors are called during stack unwinding, prevent a double
        // panic and instead prefer to leak.
        if std::thread::panicking() {
            eprintln!("Warning: neon::sync::Root leaked during a panic");
            return;
        }

        // Only panic if the event loop is still running
        if let Ok(true) = crate::context::internal::IS_RUNNING.try_with(|v| *v.borrow()) {
            panic!(
                "Must call `into_inner` or `drop` on `Root` \
                https://docs.rs/neon/latest/neon/sync/index.html#drop-safety"
            );
        }
    }

    #[cfg(feature = "napi-6")]
    fn drop(&mut self) {
        // If `None`, the `NapiRef` has already been manually dropped
        if let Some(internal) = self.internal.take() {
            let _ = self.drop_queue.call(internal.clone(), None);
        }
    }
}
<|endoftext|>


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

//! Helpers for reading directory structures from the local filesystem.

use std::fs;
use std::path::PathBuf;
use std::sync::mpsc;

use threadpool;

pub trait PathHandler<D> {
    fn handle_path(&self, D, PathBuf) -> Option<D>;
}

pub fn iterate_recursively<P: 'static + Send + Clone, W: 'static + PathHandler<P> + Send + Clone>
    (root: (PathBuf, P),
     worker: &mut W) {
    let threads = 10;
    let (push_ch, work_ch) = mpsc::sync_channel(threads);
    let pool = threadpool::ThreadPool::new(threads);

    // Insert the first task into the queue:
    push_ch.send(Some(root)).unwrap();
    let mut running_workers = 0 as i32;

    // Master thread:
    loop {
        match work_ch.recv() {
            Err(_) => unreachable!(),
            Ok(None) => {
                // A worker has completed a task.
                // We are done when no more workers are active (i.e. all tasks are done):
                running_workers -= 1;
                if running_workers == 0 {
                    break;
                }
            }
            Ok(Some((root, payload))) => {
                // Execute the task in a pool thread:
                running_workers += 1;
                let worker_ = worker.clone();
                let push_ch_ = push_ch.clone();
                pool.execute(move || {
                    let res = fs::read_dir(&root);
                    if res.is_ok() {
                        for entry in res.unwrap() {
                            if entry.is_ok() {
                                let entry = entry.unwrap();
                                let file = entry.path();
                                let path = PathBuf::from(file.to_str().unwrap());
                                let dir_opt = worker_.handle_path(payload.clone(), path);
                                if dir_opt.is_some() {
                                    push_ch_.send(Some((file.clone(), dir_opt.unwrap()))).unwrap();
                                }
                            }
                        }
                    }
                    // Count this pool thread as idle:
                    push_ch_.send(None).unwrap();
                });
            }
        }
    }
}

struct PrintPathHandler;

impl Clone for PrintPathHandler {
    fn clone(&self) -> PrintPathHandler {
        PrintPathHandler
    }
}

impl PathHandler<()> for PrintPathHandler {
    fn handle_path(&self, _: (), path: PathBuf) -> Option<()> {
        println!("{}", path.display());
        match fs::metadata(&path) {
            Ok(ref m) if m.is_dir() => Some(()),
            _ => None,
        }
    }
}
<commit_msg>Cleanup error handling in listdir.<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Helpers for reading directory structures from the local filesystem.

use std::fs;
use std::path::PathBuf;
use std::sync::mpsc;
use std::sync::{Arc, Mutex};

use threadpool;

pub trait PathHandler<D> {
    fn handle_path(&self, D, PathBuf) -> Option<D>;
}

pub fn iterate_recursively<P: 'static + Send + Clone, W: 'static + PathHandler<P> + Send + Clone>
    (first: (PathBuf, P),
     worker: &mut W) {
    let threads = 10;
    let (push_ch, work_ch) = mpsc::sync_channel(threads);
    let pool = threadpool::ThreadPool::new(threads);

    enum Work<P> {
        Done,
        More(PathBuf, P),
    }

    // Insert the first task into the queue:
    let (root, payload) = first;
    push_ch.send(Work::More(root, payload)).unwrap();
    let idle_workers = Arc::new(Mutex::new(vec![worker.clone(); threads]));
    let mut active_workers = 0;

    // Master thread:
    loop {
        match work_ch.recv() {
            Err(_) => unreachable!(),
            Ok(Work::Done) => {
                // A worker has completed a task.
                // We are done when no more workers are active (i.e. all tasks are done):
                active_workers -= 1;
                if active_workers == 0 {
                    break;
                }
            }
            Ok(Work::More(root, payload)) => {
                // Execute the task in a pool thread:
                active_workers += 1;

                let idle_workers_ = idle_workers.clone();
                let push_ch_ = push_ch.clone();
                pool.execute(move || {
                    let worker = {
                        let mut lock = idle_workers_.lock().unwrap();
                        lock.pop().expect("not enough workers")
                    };
                    match fs::read_dir(&root) {
                        Ok(dir) => {
                            for entry_res in dir {
                                match entry_res {
                                    Ok(entry) => {
                                        let file = entry.path();
                                        let path = PathBuf::from(file.to_str().unwrap());
                                        let dir_opt = worker.handle_path(payload.clone(), path);
                                        if let Some(dir) = dir_opt {
                                            push_ch_.send(Work::More(file, dir)).unwrap();
                                        }
                                    }
                                    Err(err) => {
                                        // For some reason, we failed to read this entry.
                                        // Just skip it and continue with the next.
                                        warn!("Could not read directory entry: {}", err);
                                    }
                                }
                            }
                        }
                        Err(err) => {
                            // Cannot read this directory.
                            warn!("Skipping unreadable directory {:?}: {}", root, err);
                        }
                    }
                    // Return our worker.
                    idle_workers_.lock().unwrap().push(worker);
                    // Count this pool thread as idle:
                    push_ch_.send(Work::Done).unwrap();
                });
            }
        }
    }
}

struct PrintPathHandler;

impl Clone for PrintPathHandler {
    fn clone(&self) -> PrintPathHandler {
        PrintPathHandler
    }
}

impl PathHandler<()> for PrintPathHandler {
    fn handle_path(&self, _: (), path: PathBuf) -> Option<()> {
        println!("{}", path.display());
        match fs::metadata(&path) {
            Ok(ref m) if m.is_dir() => Some(()),
            _ => None,
        }
    }
}
<|endoftext|>


<commit_before>pub mod raw {
   #![allow(non_camel_case_types)]

   use libc::{c_void, c_char, c_int, c_ulong};

   use apr::raw::{apr_pool_t};

   use httpd::raw::{process_rec, server_rec};

   #[repr(C)]
   pub struct command_rec;

   pub type rewrite_args_fn = extern "C" fn(
      process: *mut process_rec
   );

   pub type create_dir_config_fn = extern "C" fn(
      p: *mut apr_pool_t, dir: *mut c_char
   ) -> *mut c_void;

   pub type merge_config_fn = extern "C" fn(
      p: *mut apr_pool_t, base_conf: *mut c_void, new_conf: *mut c_void
   ) -> *mut c_void;

   pub type create_server_config_fn = extern "C" fn(
      p: *mut apr_pool_t, s: *mut server_rec
   ) -> *mut c_void;

   pub type register_hooks_fn = extern "C" fn(
      p: *mut apr_pool_t
   );

   pub type module = module_struct;

   #[repr(C)]
   pub struct module_struct {
      pub version: c_int,

      pub minor_version: c_int,

      pub module_index: c_int,

      pub name: *const c_char,

      pub dynamic_load_handle: *mut c_void,

      pub next: *mut module_struct,

      pub magic: c_ulong,

      pub rewrite_args: Option<rewrite_args_fn>,

      pub create_dir_config: Option<create_dir_config_fn>,

      pub merge_dir_config: Option<merge_config_fn>,

      pub create_server_config: Option<create_server_config_fn>,

      pub merge_server_config: Option<merge_config_fn>,

      pub cmds: *const command_rec,

      pub register_hooks: ::std::option::Option<register_hooks_fn>
   }
}
<commit_msg>Formatting the config structure better.<commit_after>pub mod raw {
   #![allow(non_camel_case_types)]

   use libc::{c_void, c_char, c_int, c_ulong};

   use apr::raw::{apr_pool_t};

   use httpd::raw::{process_rec, server_rec};

   #[repr(C)]
   pub struct command_rec;

   pub type rewrite_args_fn = extern "C" fn(
      process: *mut process_rec
   );

   pub type create_dir_config_fn = extern "C" fn(
      p: *mut apr_pool_t, dir: *mut c_char
   ) -> *mut c_void;

   pub type merge_config_fn = extern "C" fn(
      p: *mut apr_pool_t, base_conf: *mut c_void, new_conf: *mut c_void
   ) -> *mut c_void;

   pub type create_server_config_fn = extern "C" fn(
      p: *mut apr_pool_t, s: *mut server_rec
   ) -> *mut c_void;

   pub type register_hooks_fn = extern "C" fn(
      p: *mut apr_pool_t
   );

   pub type module = module_struct;

   #[repr(C)]
   pub struct module_struct {
      pub version: c_int,
      pub minor_version: c_int,
      pub module_index: c_int,
      pub name: *const c_char,
      pub dynamic_load_handle: *mut c_void,
      pub next: *mut module_struct,
      pub magic: c_ulong,
      pub rewrite_args: Option<rewrite_args_fn>,
      pub create_dir_config: Option<create_dir_config_fn>,
      pub merge_dir_config: Option<merge_config_fn>,
      pub create_server_config: Option<create_server_config_fn>,
      pub merge_server_config: Option<merge_config_fn>,
      pub cmds: *const command_rec,
      pub register_hooks: ::std::option::Option<register_hooks_fn>
   }
}
<|endoftext|>


<commit_before>extern crate openssl;

use std::io;
use std::fmt;
use std::error;
use self::openssl::ssl::{self, SslContext, SslMethod, SSL_VERIFY_PEER};
use self::openssl::ssl::error::SslError;

pub struct Error(SslError);

impl error::Error for Error {
    fn description(&self) -> &str {
        error::Error::description(&self.0)
    }

    fn cause(&self) -> Option<&error::Error> {
        error::Error::cause(&self.0)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, fmt)
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl From<SslError> for Error {
    fn from(err: SslError) -> Error {
        Error(err)
    }
}

pub struct ClientBuilder(SslContext);

impl ClientBuilder {
    pub fn new() -> Result<ClientBuilder, Error> {
        let mut ctx = try!(SslContext::new(SslMethod::Sslv23));
        ctx.set_verify(SSL_VERIFY_PEER, None);
        try!(ctx.set_default_verify_paths());
        Ok(ClientBuilder(ctx))
    }

    // FIXME hostname verification
    pub fn handshake<S>(&mut self, _domain: &str, stream: S) -> Result<TlsStream<S>, Error>
        where S: io::Read + io::Write
    {
        let s = try!(ssl::SslStream::connect(&self.0, stream));
        Ok(TlsStream(s))
    }
}

pub struct TlsStream<S>(ssl::SslStream<S>);

impl<S: io::Read + io::Write> TlsStream<S> {
    pub fn get_ref(&self) -> &S {
        self.0.get_ref()
    }

    pub fn get_mut(&mut self) -> &mut S {
        self.0.get_mut()
    }
}

impl<S: io::Read + io::Write> io::Read for TlsStream<S> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl<S: io::Read + io::Write> io::Write for TlsStream<S> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}
<commit_msg>Set hostname when connecting with OpenSSL<commit_after>extern crate openssl;

use std::io;
use std::fmt;
use std::error;
use self::openssl::ssl::{self, SslContext, SslMethod, SSL_VERIFY_PEER, IntoSsl};
use self::openssl::ssl::error::SslError;

pub struct Error(SslError);

impl error::Error for Error {
    fn description(&self) -> &str {
        error::Error::description(&self.0)
    }

    fn cause(&self) -> Option<&error::Error> {
        error::Error::cause(&self.0)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.0, fmt)
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.0, fmt)
    }
}

impl From<SslError> for Error {
    fn from(err: SslError) -> Error {
        Error(err)
    }
}

pub struct ClientBuilder(SslContext);

impl ClientBuilder {
    pub fn new() -> Result<ClientBuilder, Error> {
        let mut ctx = try!(SslContext::new(SslMethod::Sslv23));
        ctx.set_verify(SSL_VERIFY_PEER, None);
        try!(ctx.set_default_verify_paths());
        Ok(ClientBuilder(ctx))
    }

    // FIXME hostname verification
    pub fn handshake<S>(&mut self, domain: &str, stream: S) -> Result<TlsStream<S>, Error>
        where S: io::Read + io::Write
    {
        let ssl = try!(self.0.into_ssl());
        try!(ssl.set_hostname(domain));
        let s = try!(ssl::SslStream::connect(ssl, stream));
        Ok(TlsStream(s))
    }
}

pub struct TlsStream<S>(ssl::SslStream<S>);

impl<S: io::Read + io::Write> TlsStream<S> {
    pub fn get_ref(&self) -> &S {
        self.0.get_ref()
    }

    pub fn get_mut(&mut self) -> &mut S {
        self.0.get_mut()
    }
}

impl<S: io::Read + io::Write> io::Read for TlsStream<S> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }
}

impl<S: io::Read + io::Write> io::Write for TlsStream<S> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}
<|endoftext|>


<commit_before>use std::num::{Zero, One};
use nalgebra::na::{AlgebraicVecExt, Cast, Dim, Identity, Translation, Rotate, Transform};
use narrow::algorithm::simplex::Simplex;
use narrow::algorithm::johnson_simplex::JohnsonSimplex;
use geom::{Cylinder, Cone, Capsule, MinkowskiSum, Implicit};
use ray::{Ray, RayCast, RayCastWithTransform};
use ray;

/// Projects the origin on a geometry unsing the GJK algorithm.
///
/// # Arguments:
///     * geom - the geometry to project the origin on
///     * simplex - the simplex to be used by the GJK algorithm. It must be already initialized
///     with at least one point on the geometry boundary.
pub fn gjk_toi_and_normal_with_ray<S: Simplex<N, V>,
                                   G: Implicit<N, V, M>,
                                   N: Ord + Num + Float + Cast<f32> + ToStr,
                                   V: AlgebraicVecExt<N> + Clone + ToStr,
                                   M: Translation<V>>(
                                   m:       &M,
                                   geom:    &G,
                                   simplex: &mut S,
                                   ray:     &Ray<V>)
                                   -> Option<(N, V)> {
    let mut ltoi: N = Zero::zero();

    let _eps: N  = Float::epsilon();
    let _eps_tol = _eps * Cast::from(100.0);
    let _eps_rel = _eps.sqrt();
    let _dim     = Dim::dim(None::<V>);

    // initialization
    let mut curr_ray   = Ray::new(ray.orig.clone(), ray.dir.clone());
    let mut dir        = curr_ray.orig - m.translation();

    if dir.is_zero() {
        dir.set(0, One::one())
    }

    let mut old_sq_len: N = Bounded::max_value();

    // FIXME: this converges in more than 100 iterations… something is wrong here…
    loop {
        dir.normalize();

        let support_point = geom.support_point(m, &dir);

        // Clip the ray on the support plane (None <=> t < 0)
        // The configurations are:
        //   dir.dot(ray.dir)  |   t   |               Action
        // −−−−−−−−−−−−−−−−−−−−+−−−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
        //          < 0        |  < 0  | Continue.
        //          < 0        |  > 0  | New lower bound, move the origin.
        //          > 0        |  < 0  | Miss. No intersection.
        //          > 0        |  > 0  | New higher bound.
        match ray::plane_toi_with_ray(&support_point, &dir, &curr_ray) {
            Some(t) => {
                if dir.dot(&ray.dir) < Zero::zero() {
                    // new lower bound
                    if t <= _eps_rel * ltoi {
                        return Some((ltoi, dir))
                    }

                    ltoi   = ltoi + t;
                    curr_ray.orig = ray.orig + ray.dir * ltoi;
                    dir    = curr_ray.orig - support_point;
                    simplex.reset(-dir);
                    let _M: N = Bounded::max_value();
                    old_sq_len = _M;
                    continue
                }
            },
            None => {
                if dir.dot(&ray.dir) > Zero::zero() {
                    // miss
                    return None
                }
            }
        }

        simplex.add_point(support_point - curr_ray.orig);

        let proj = simplex.project_origin_and_reduce();
        let sq_len_dir = proj.sqnorm();

        if (simplex.dimension() == _dim ||
            sq_len_dir >= old_sq_len    || // FIXME: hacky way to prevent infinite loop…
            sq_len_dir <= _eps_tol * simplex.max_sq_len()
           ) {
            return Some((ltoi, dir)) // FIXME: dir or -proj ?
        }

        old_sq_len = sq_len_dir;
        dir        = -proj;
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr>
RayCast<N, V> for Cylinder<N> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr,
     M: Transform<V> + Rotate<V>>
RayCastWithTransform<N, V, M> for Cylinder<N> { }

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr>
RayCast<N, V> for Cone<N> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr,
     M: Transform<V> + Rotate<V>>
RayCastWithTransform<N, V, M> for Cone<N> { }

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr>
RayCast<N, V> for Capsule<N> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr,
     M: Transform<V> + Rotate<V>>
RayCastWithTransform<N, V, M> for Capsule<N> { }

impl<'self,
     N:  Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V:  AlgebraicVecExt<N> + Clone + ToStr,
     G1: Implicit<N, V, M>,
     G2: Implicit<N, V, M>,
     M>
RayCast<N, V> for MinkowskiSum<'self, M, G1, G2> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<'self,
     N:  Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V:  AlgebraicVecExt<N> + Clone + ToStr,
     G1: Implicit<N, V, M>,
     G2: Implicit<N, V, M>,
     M:  Rotate<V> + Transform<V>>
RayCastWithTransform<N, V, M> for MinkowskiSum<'self, M, G1, G2> { }
<commit_msg>Fix normal computation for the ray cast on an implicit shape.<commit_after>use std::num::{Zero, One};
use nalgebra::na::{AlgebraicVecExt, Cast, Dim, Identity, Translation, Rotate, Transform};
use narrow::algorithm::simplex::Simplex;
use narrow::algorithm::johnson_simplex::JohnsonSimplex;
use geom::{Cylinder, Cone, Capsule, MinkowskiSum, Implicit};
use ray::{Ray, RayCast, RayCastWithTransform};
use ray;

/// Projects the origin on a geometry unsing the GJK algorithm.
///
/// # Arguments:
///     * geom - the geometry to project the origin on
///     * simplex - the simplex to be used by the GJK algorithm. It must be already initialized
///     with at least one point on the geometry boundary.
pub fn gjk_toi_and_normal_with_ray<S: Simplex<N, V>,
                                   G: Implicit<N, V, M>,
                                   N: Ord + Num + Float + Cast<f32> + ToStr,
                                   V: AlgebraicVecExt<N> + Clone + ToStr,
                                   M: Translation<V>>(
                                   m:       &M,
                                   geom:    &G,
                                   simplex: &mut S,
                                   ray:     &Ray<V>)
                                   -> Option<(N, V)> {
    let mut ltoi: N = Zero::zero();

    let _eps: N  = Float::epsilon();
    let _eps_tol = _eps * Cast::from(100.0);
    let _eps_rel = _eps.sqrt();
    let _dim     = Dim::dim(None::<V>);

    // initialization
    let mut curr_ray   = Ray::new(ray.orig.clone(), ray.dir.clone());
    let mut dir        = curr_ray.orig - m.translation();

    if dir.is_zero() {
        dir.set(0, One::one())
    }

    let mut old_sq_len: N = Bounded::max_value();

    let mut ldir = dir.clone();
    // FIXME: this converges in more than 100 iterations… something is wrong here…
    loop {
        dir.normalize();

        let support_point = geom.support_point(m, &dir);

        // Clip the ray on the support plane (None <=> t < 0)
        // The configurations are:
        //   dir.dot(ray.dir)  |   t   |               Action
        // −−−−−−−−−−−−−−−−−−−−+−−−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
        //          < 0        |  < 0  | Continue.
        //          < 0        |  > 0  | New lower bound, move the origin.
        //          > 0        |  < 0  | Miss. No intersection.
        //          > 0        |  > 0  | New higher bound.
        match ray::plane_toi_with_ray(&support_point, &dir, &curr_ray) {
            Some(t) => {
                if dir.dot(&ray.dir) < Zero::zero() {
                    // new lower bound
                    ldir = dir.clone();
                    if false { // t <= _eps_rel * ltoi {
                        return Some((ltoi, dir))
                    }

                    ltoi   = ltoi + t;
                    curr_ray.orig = ray.orig + ray.dir * ltoi;
                    dir    = curr_ray.orig - support_point;
                    simplex.reset(-dir);
                    let _M: N = Bounded::max_value();
                    old_sq_len = _M;
                    continue
                }
            },
            None => {
                if dir.dot(&ray.dir) > Zero::zero() {
                    // miss
                    return None
                }
            }
        }

        simplex.add_point(support_point - curr_ray.orig);

        let proj = simplex.project_origin_and_reduce();
        let sq_len_dir = proj.sqnorm();

        if (simplex.dimension() == _dim ||
            sq_len_dir >= old_sq_len    || // FIXME: hacky way to prevent infinite loop…
            sq_len_dir <= _eps_tol * simplex.max_sq_len()
           ) {
            return Some((ltoi, ldir)) // FIXME: dir or -proj ?
        }

        old_sq_len = sq_len_dir;
        dir        = -proj;
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr>
RayCast<N, V> for Cylinder<N> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr,
     M: Transform<V> + Rotate<V>>
RayCastWithTransform<N, V, M> for Cylinder<N> { }

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr>
RayCast<N, V> for Cone<N> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr,
     M: Transform<V> + Rotate<V>>
RayCastWithTransform<N, V, M> for Cone<N> { }

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr>
RayCast<N, V> for Capsule<N> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<N: Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V: AlgebraicVecExt<N> + Clone + ToStr,
     M: Transform<V> + Rotate<V>>
RayCastWithTransform<N, V, M> for Capsule<N> { }

impl<'self,
     N:  Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V:  AlgebraicVecExt<N> + Clone + ToStr,
     G1: Implicit<N, V, M>,
     G2: Implicit<N, V, M>,
     M>
RayCast<N, V> for MinkowskiSum<'self, M, G1, G2> {
    fn toi_and_normal_with_ray(&self, ray: &Ray<V>) -> Option<(N, V)> {
        gjk_toi_and_normal_with_ray(&Identity::new(), self, &mut JohnsonSimplex::<N, V>::new_w_tls(), ray)
    }
}

impl<'self,
     N:  Ord + Num + Float + Cast<f32> + Clone + ToStr,
     V:  AlgebraicVecExt<N> + Clone + ToStr,
     G1: Implicit<N, V, M>,
     G2: Implicit<N, V, M>,
     M:  Rotate<V> + Transform<V>>
RayCastWithTransform<N, V, M> for MinkowskiSum<'self, M, G1, G2> { }
<|endoftext|>