<commit_before>use super::*;
use crate::client::Context;
use crate::model::channel::Message;
use uwl::Stream;

pub mod map;

use map::{CommandMap, GroupMap, ParseMap};

use std::borrow::Cow;

#[inline]
fn to_lowercase<'a>(config: &Configuration, s: &'a str) -> Cow<'a, str> {
    if config.case_insensitive {
        Cow::Owned(s.to_lowercase())
    } else {
        Cow::Borrowed(s)
    }
}

/// Parse a mention in the message that is of either the direct (`<@id>`) or nickname (`<@!id>`) syntax,
/// and compare the encoded `id` with the id from [`Configuration::on_mention`] for a match.
/// Returns `Some(<id>)` on success, `None` otherwise.
///
/// [`Configuration::on_mention`]: ../struct.Configuration.html#method.on_mention
pub fn mention<'a>(stream: &mut Stream<'a>, config: &Configuration) -> Option<&'a str> {
    let on_mention = config.on_mention.as_ref().map(String::as_str)?;

    let start = stream.offset();

    if !stream.eat("<@") {
        return None;
    }

    // Optional.
    stream.eat("!");

    let id = stream.take_while(|b| b.is_ascii_digit());

    if !stream.eat(">") {
        // Backtrack to where we were.
        stream.set(start);

        return None;
    }

    if id == on_mention {
        Some(id)
    } else {
        stream.set(start);

        None
    }
}

fn find_prefix<'a>(
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    stream: &Stream<'a>,
) -> Option<Cow<'a, str>> {
    let try_match = |prefix: &str| {
        let peeked = stream.peek_for_char(prefix.chars().count());
        let peeked = to_lowercase(config, peeked);

        if prefix == &peeked {
            Some(peeked)
        } else {
            None
        }
    };

    for f in &config.dynamic_prefixes {
        if let Some(p) = f(ctx, msg) {
            let p = to_lowercase(config, &p);
            if let Some(p) = try_match(&p) {
                return Some(p);
            }
        }
    }

    config.prefixes.iter().find_map(|p| try_match(&p))
}

/// Parse a prefix in the message.
///
/// The "prefix" may be one of the following:
/// - A mention (`<@id>`/`<@!id>`)
/// - A dynamically constructed prefix ([`Configuration::dynamic_prefix`])
/// - A static prefix ([`Configuration::prefix`])
/// - Nothing
///
/// In all cases, whitespace after the prefix is cleared.
///
/// [`Configuration::dynamic_prefix`]: ../struct.Configuration.html#method.dynamic_prefix
/// [`Configuration::prefix`]: ../struct.Configuration.html#method.prefix
pub fn prefix<'a>(
    ctx: &Context,
    msg: &Message,
    stream: &mut Stream<'a>,
    config: &Configuration,
) -> Option<Cow<'a, str>> {
    if let Some(id) = mention(stream, config) {
        stream.take_while_char(|c| c.is_whitespace());

        return Some(Cow::Borrowed(id));
    }

    let prefix = find_prefix(ctx, msg, config, stream);

    if let Some(prefix) = &prefix {
        stream.increment(prefix.len());
    }

    if config.with_whitespace.prefixes {
        stream.take_while_char(|c| c.is_whitespace());
    }

    prefix
}

/// Checked per valid group or command in the message.
fn check_discrepancy(
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    options: &impl CommonOptions,
) -> Result<(), DispatchError> {
    if options.owners_only() && !config.owners.contains(&msg.author.id) {
        return Err(DispatchError::OnlyForOwners);
    }

    if options.only_in() == OnlyIn::Dm && !msg.is_private() {
        return Err(DispatchError::OnlyForDM);
    }

    if (!config.allow_dm || options.only_in() == OnlyIn::Guild) && msg.is_private() {
        return Err(DispatchError::OnlyForGuilds);
    }

    #[cfg(feature = "cache")]
    {
        if let Some(guild_id) = msg.guild_id {
            let guild = match guild_id.to_guild_cached(&ctx) {
                Some(g) => g,
                None => return Ok(()),
            };

            let guild = guild.read();

            let perms = guild.user_permissions_in(msg.channel_id, msg.author.id);

            if !perms.contains(*options.required_permissions())
                && !(options.owner_privilege() && config.owners.contains(&msg.author.id))
            {
                return Err(DispatchError::LackingPermissions(
                    *options.required_permissions(),
                ));
            }

            if let Some(member) = guild.members.get(&msg.author.id) {
                if !perms.administrator() && !has_correct_roles(options, &guild, &member) {
                    return Err(DispatchError::LackingRole);
                }
            }
        }
    }

    Ok(())
}

fn try_parse<M: ParseMap>(
    stream: &mut Stream<'_>,
    map: &M,
    by_space: bool,
    f: impl Fn(&str) -> String,
) -> (String, Option<M::Storage>) {
    if by_space {
        let n = f(stream.peek_until_char(|c| c.is_whitespace()));

        let o = map.get(&n);

        (n, o)
    } else {
        let mut n = f(stream.peek_for_char(map.max_length()));
        let mut o = None;

        for _ in 0..(map.max_length() - map.min_length()) {
            o = map.get(&n);

            if o.is_some() {
                break;
            }

            n.pop();
        }

        (n, o)
    }
}

fn parse_cmd(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &CommandMap,
) -> Result<&'static Command, ParseError> {
    let (n, r) = try_parse(stream, map, config.by_space, |s| {
        to_lowercase(config, s).into_owned()
    });

    if config.disabled_commands.contains(&n) {
        return Err(ParseError::Dispatch(DispatchError::CommandDisabled(n)));
    }

    if let Some((cmd, map)) = r {
        stream.increment(n.len());

        if config.with_whitespace.commands {
            stream.take_while_char(|c| c.is_whitespace());
        }

        check_discrepancy(ctx, msg, config, &cmd.options)?;

        if map.is_empty() {
            return Ok(cmd);
        }

        return match parse_cmd(stream, ctx, msg, config, &map) {
            Err(ParseError::UnrecognisedCommand(Some(_))) => Ok(cmd),
            res => res,
        };
    }

    Err(ParseError::UnrecognisedCommand(Some(n.to_string())))
}

fn parse_group(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &GroupMap,
) -> Result<(&'static CommandGroup, Arc<CommandMap>), ParseError> {
    let (n, o) = try_parse(stream, map, config.by_space, ToString::to_string);

    if let Some((group, map, commands)) = o {
        stream.increment(n.len());

        if config.with_whitespace.groups {
            stream.take_while_char(|c| c.is_whitespace());
        }

        check_discrepancy(ctx, msg, config, &group.options)?;

        if map.is_empty() {
            return Ok((group, commands));
        }

        return match parse_group(stream, ctx, msg, config, &map) {
            Err(ParseError::UnrecognisedCommand(None)) => Ok((group, commands)),
            res => res,
        };
    }

    Err(ParseError::UnrecognisedCommand(None))
}

#[inline]
fn handle_command(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &CommandMap,
    group: &'static CommandGroup,
) -> Result<Invoke, ParseError> {
    match parse_cmd(stream, ctx, msg, config, map) {
        Ok(command) => Ok(Invoke::Command { group, command }),
        Err(err) => match group.options.default_command {
            Some(command) => Ok(Invoke::Command { group, command }),
            None => Err(err),
        },
    }
}

#[inline]
fn handle_group(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &GroupMap,
) -> Result<Invoke, ParseError> {
    parse_group(stream, ctx, msg, config, map)
        .and_then(|(group, map)| handle_command(stream, ctx, msg, config, &map, group))
}

#[derive(Debug)]
pub enum ParseError {
    UnrecognisedCommand(Option<String>),
    Dispatch(DispatchError),
}

impl From<DispatchError> for ParseError {
    #[inline]
    fn from(err: DispatchError) -> Self {
        ParseError::Dispatch(err)
    }
}

/// Parse a command from the message.
///
/// The "command" may be:
/// 1. A *help command* that provides a friendly browsing interface of all groups and commands,
/// explaining what each of them are, how they are layed out and how to invoke them.
/// There can only one help command registered, but might have many names defined for invocation of itself.
///
/// 2. A command defined under another command or a group, which may also belong to another group and so on.
/// To invoke this command, all names and prefixes of its parent commands and groups must be specified before it.
pub fn command(
    ctx: &Context,
    msg: &Message,
    stream: &mut Stream<'_>,
    groups: &[(&'static CommandGroup, Map)],
    config: &Configuration,
    help_was_set: Option<&[&'static str]>,
) -> Result<Invoke, ParseError> {
    // Precedence is taken over commands named as one of the help names.
    if let Some(names) = help_was_set {
        for name in names {
            let n = to_lowercase(config, stream.peek_for_char(name.chars().count()));

            if name == &n {
                stream.increment(n.len());

                stream.take_while_char(|c| c.is_whitespace());

                return Ok(Invoke::Help(name));
            }
        }
    }

    let mut last = Err(ParseError::UnrecognisedCommand(None));
    let mut is_prefixless = false;

    for (group, map) in groups {
        match map {
            // Includes [group] itself.
            Map::WithPrefixes(map) => {
                let res = handle_group(stream, ctx, msg, config, map);

                if res.is_ok() {
                    return res;
                }

                if !is_prefixless {
                    last = res;
                }
            }
            Map::Prefixless(subgroups, commands) => {
                let res = handle_group(stream, ctx, msg, config, subgroups);

                if res.is_ok() {
                    check_discrepancy(ctx, msg, config, &group.options)?;

                    return res;
                }

                let res = handle_command(stream, ctx, msg, config, commands, group);

                if res.is_ok() {
                    check_discrepancy(ctx, msg, config, &group.options)?;

                    is_prefixless = true;
                    return res;
                }

                last = res;
            }
        }
    }

    last
}

#[derive(Debug)]
pub enum Invoke {
    Command {
        group: &'static CommandGroup,
        command: &'static Command,
    },
    Help(&'static str),
}
<commit_msg>Remove unnecessary return to fix `unrecognised_command` (#906)<commit_after>use super::*;
use crate::client::Context;
use crate::model::channel::Message;
use uwl::Stream;

pub mod map;

use map::{CommandMap, GroupMap, ParseMap};

use std::borrow::Cow;

#[inline]
fn to_lowercase<'a>(config: &Configuration, s: &'a str) -> Cow<'a, str> {
    if config.case_insensitive {
        Cow::Owned(s.to_lowercase())
    } else {
        Cow::Borrowed(s)
    }
}

/// Parse a mention in the message that is of either the direct (`<@id>`) or nickname (`<@!id>`) syntax,
/// and compare the encoded `id` with the id from [`Configuration::on_mention`] for a match.
/// Returns `Some(<id>)` on success, `None` otherwise.
///
/// [`Configuration::on_mention`]: ../struct.Configuration.html#method.on_mention
pub fn mention<'a>(stream: &mut Stream<'a>, config: &Configuration) -> Option<&'a str> {
    let on_mention = config.on_mention.as_ref().map(String::as_str)?;

    let start = stream.offset();

    if !stream.eat("<@") {
        return None;
    }

    // Optional.
    stream.eat("!");

    let id = stream.take_while(|b| b.is_ascii_digit());

    if !stream.eat(">") {
        // Backtrack to where we were.
        stream.set(start);

        return None;
    }

    if id == on_mention {
        Some(id)
    } else {
        stream.set(start);

        None
    }
}

fn find_prefix<'a>(
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    stream: &Stream<'a>,
) -> Option<Cow<'a, str>> {
    let try_match = |prefix: &str| {
        let peeked = stream.peek_for_char(prefix.chars().count());
        let peeked = to_lowercase(config, peeked);

        if prefix == &peeked {
            Some(peeked)
        } else {
            None
        }
    };

    for f in &config.dynamic_prefixes {
        if let Some(p) = f(ctx, msg) {
            let p = to_lowercase(config, &p);
            if let Some(p) = try_match(&p) {
                return Some(p);
            }
        }
    }

    config.prefixes.iter().find_map(|p| try_match(&p))
}

/// Parse a prefix in the message.
///
/// The "prefix" may be one of the following:
/// - A mention (`<@id>`/`<@!id>`)
/// - A dynamically constructed prefix ([`Configuration::dynamic_prefix`])
/// - A static prefix ([`Configuration::prefix`])
/// - Nothing
///
/// In all cases, whitespace after the prefix is cleared.
///
/// [`Configuration::dynamic_prefix`]: ../struct.Configuration.html#method.dynamic_prefix
/// [`Configuration::prefix`]: ../struct.Configuration.html#method.prefix
pub fn prefix<'a>(
    ctx: &Context,
    msg: &Message,
    stream: &mut Stream<'a>,
    config: &Configuration,
) -> Option<Cow<'a, str>> {
    if let Some(id) = mention(stream, config) {
        stream.take_while_char(|c| c.is_whitespace());

        return Some(Cow::Borrowed(id));
    }

    let prefix = find_prefix(ctx, msg, config, stream);

    if let Some(prefix) = &prefix {
        stream.increment(prefix.len());
    }

    if config.with_whitespace.prefixes {
        stream.take_while_char(|c| c.is_whitespace());
    }

    prefix
}

/// Checked per valid group or command in the message.
fn check_discrepancy(
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    options: &impl CommonOptions,
) -> Result<(), DispatchError> {
    if options.owners_only() && !config.owners.contains(&msg.author.id) {
        return Err(DispatchError::OnlyForOwners);
    }

    if options.only_in() == OnlyIn::Dm && !msg.is_private() {
        return Err(DispatchError::OnlyForDM);
    }

    if (!config.allow_dm || options.only_in() == OnlyIn::Guild) && msg.is_private() {
        return Err(DispatchError::OnlyForGuilds);
    }

    #[cfg(feature = "cache")]
    {
        if let Some(guild_id) = msg.guild_id {
            let guild = match guild_id.to_guild_cached(&ctx) {
                Some(g) => g,
                None => return Ok(()),
            };

            let guild = guild.read();

            let perms = guild.user_permissions_in(msg.channel_id, msg.author.id);

            if !perms.contains(*options.required_permissions())
                && !(options.owner_privilege() && config.owners.contains(&msg.author.id))
            {
                return Err(DispatchError::LackingPermissions(
                    *options.required_permissions(),
                ));
            }

            if let Some(member) = guild.members.get(&msg.author.id) {
                if !perms.administrator() && !has_correct_roles(options, &guild, &member) {
                    return Err(DispatchError::LackingRole);
                }
            }
        }
    }

    Ok(())
}

fn try_parse<M: ParseMap>(
    stream: &mut Stream<'_>,
    map: &M,
    by_space: bool,
    f: impl Fn(&str) -> String,
) -> (String, Option<M::Storage>) {
    if by_space {
        let n = f(stream.peek_until_char(|c| c.is_whitespace()));

        let o = map.get(&n);

        (n, o)
    } else {
        let mut n = f(stream.peek_for_char(map.max_length()));
        let mut o = None;

        for _ in 0..(map.max_length() - map.min_length()) {
            o = map.get(&n);

            if o.is_some() {
                break;
            }

            n.pop();
        }

        (n, o)
    }
}

fn parse_cmd(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &CommandMap,
) -> Result<&'static Command, ParseError> {
    let (n, r) = try_parse(stream, map, config.by_space, |s| {
        to_lowercase(config, s).into_owned()
    });

    if config.disabled_commands.contains(&n) {
        return Err(ParseError::Dispatch(DispatchError::CommandDisabled(n)));
    }

    if let Some((cmd, map)) = r {
        stream.increment(n.len());

        if config.with_whitespace.commands {
            stream.take_while_char(|c| c.is_whitespace());
        }

        check_discrepancy(ctx, msg, config, &cmd.options)?;

        if map.is_empty() {
            return Ok(cmd);
        }

        return match parse_cmd(stream, ctx, msg, config, &map) {
            Err(ParseError::UnrecognisedCommand(Some(_))) => Ok(cmd),
            res => res,
        };
    }

    Err(ParseError::UnrecognisedCommand(Some(n.to_string())))
}

fn parse_group(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &GroupMap,
) -> Result<(&'static CommandGroup, Arc<CommandMap>), ParseError> {
    let (n, o) = try_parse(stream, map, config.by_space, ToString::to_string);

    if let Some((group, map, commands)) = o {
        stream.increment(n.len());

        if config.with_whitespace.groups {
            stream.take_while_char(|c| c.is_whitespace());
        }

        check_discrepancy(ctx, msg, config, &group.options)?;

        if map.is_empty() {
            return Ok((group, commands));
        }

        return match parse_group(stream, ctx, msg, config, &map) {
            Err(ParseError::UnrecognisedCommand(None)) => Ok((group, commands)),
            res => res,
        };
    }

    Err(ParseError::UnrecognisedCommand(None))
}

#[inline]
fn handle_command(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &CommandMap,
    group: &'static CommandGroup,
) -> Result<Invoke, ParseError> {
    match parse_cmd(stream, ctx, msg, config, map) {
        Ok(command) => Ok(Invoke::Command { group, command }),
        Err(err) => match group.options.default_command {
            Some(command) => Ok(Invoke::Command { group, command }),
            None => Err(err),
        },
    }
}

#[inline]
fn handle_group(
    stream: &mut Stream<'_>,
    ctx: &Context,
    msg: &Message,
    config: &Configuration,
    map: &GroupMap,
) -> Result<Invoke, ParseError> {
    parse_group(stream, ctx, msg, config, map)
        .and_then(|(group, map)| handle_command(stream, ctx, msg, config, &map, group))
}

#[derive(Debug)]
pub enum ParseError {
    UnrecognisedCommand(Option<String>),
    Dispatch(DispatchError),
}

impl From<DispatchError> for ParseError {
    #[inline]
    fn from(err: DispatchError) -> Self {
        ParseError::Dispatch(err)
    }
}

/// Parse a command from the message.
///
/// The "command" may be:
/// 1. A *help command* that provides a friendly browsing interface of all groups and commands,
/// explaining what each of them are, how they are layed out and how to invoke them.
/// There can only one help command registered, but might have many names defined for invocation of itself.
///
/// 2. A command defined under another command or a group, which may also belong to another group and so on.
/// To invoke this command, all names and prefixes of its parent commands and groups must be specified before it.
pub fn command(
    ctx: &Context,
    msg: &Message,
    stream: &mut Stream<'_>,
    groups: &[(&'static CommandGroup, Map)],
    config: &Configuration,
    help_was_set: Option<&[&'static str]>,
) -> Result<Invoke, ParseError> {
    // Precedence is taken over commands named as one of the help names.
    if let Some(names) = help_was_set {
        for name in names {
            let n = to_lowercase(config, stream.peek_for_char(name.chars().count()));

            if name == &n {
                stream.increment(n.len());

                stream.take_while_char(|c| c.is_whitespace());

                return Ok(Invoke::Help(name));
            }
        }
    }

    let mut last = Err(ParseError::UnrecognisedCommand(None));
    let mut is_prefixless = false;

    for (group, map) in groups {
        match map {
            // Includes [group] itself.
            Map::WithPrefixes(map) => {
                let res = handle_group(stream, ctx, msg, config, map);

                if res.is_ok() {
                    return res;
                }

                if !is_prefixless {
                    last = res;
                }
            }
            Map::Prefixless(subgroups, commands) => {
                let res = handle_group(stream, ctx, msg, config, subgroups);

                if res.is_ok() {
                    check_discrepancy(ctx, msg, config, &group.options)?;

                    return res;
                }

                let res = handle_command(stream, ctx, msg, config, commands, group);

                if res.is_ok() {
                    check_discrepancy(ctx, msg, config, &group.options)?;

                    is_prefixless = true;
                }

                last = res;
            }
        }
    }

    last
}

#[derive(Debug)]
pub enum Invoke {
    Command {
        group: &'static CommandGroup,
        command: &'static Command,
    },
    Help(&'static str),
}
<|endoftext|>


<commit_before>use super::{Interval, IntervalEnd, IntervalCollisionObject};
use collision::Collidable;
use ::geometry::*;

#[derive(Debug, Clone)]
pub struct IntervalCollection {
    pub start: IntervalEnd,
    pub end: IntervalEnd,
    intervals: Vec<Interval>
}

impl IntervalCollection {
    const ERRORMARGIN: f64 = 0.0001;

    pub fn new(start: IntervalEnd, end: IntervalEnd, intervals: Vec<Interval>) -> Self {
        Self {
            start,
            end,
            intervals
        }
    }

    fn relative_error_margin(&self) -> f64 {
        Self::ERRORMARGIN * (self.end.value() - self.start.value())
    }

    fn get_starts(&self) -> Vec<IntervalEnd> {
        self.intervals.iter().map(|end| { end.get_start().clone() }).collect()
    }

    fn get_ends(&self) -> Vec<IntervalEnd> {
        self.intervals.iter().map(|end| { end.get_end().clone() }).collect()
    }

    pub fn get_start_end_interval(&self) -> Interval {
        Interval::new(self.start, self.end)
    }

    pub fn invert(&self) -> IntervalCollection {
        let mut inv_intervals: Vec<Interval> = Vec::new();

        let start_included = self.start.equals(&self.intervals[0].get_start(), self.relative_error_margin());
        if !start_included {
            let first_interval = Interval::new(self.start, self.intervals[0].get_start());
            inv_intervals.push(first_interval);
        }

        for (end_prev, start_next) in self.get_ends().iter().zip(self.get_starts().iter().skip(1)) {
            inv_intervals.push(Interval::new(end_prev.clone(), start_next.clone()));
        }

        let end_included = self.end.equals(&self.intervals[0].get_end(), self.relative_error_margin());
        if !end_included {
            let last_interval = Interval::new(self.end, self.intervals[0].get_end());
            inv_intervals.push(last_interval);
        }

        IntervalCollection {
            start: self.start,
            end: self.end,
            intervals: inv_intervals
        }
    }

    pub fn contains(&self, point: f64) -> bool {
        self.intervals.iter().fold(false, |acc, int| {int.contains(point) || acc})
    }

    pub fn get_collision_objects(&self) -> Vec<IntervalCollisionObject> {
        self.intervals.iter().map(|interval| {interval.get_collision_object()} ).collect()
    }

    pub fn wrap_to_interval(&self, int: Interval) -> IntervalCollection {
        let wrapped_intervals = self.intervals.iter().flat_map(|inner_int| {int.wrap_interval_to(*inner_int)}).collect();
        Self::new(int.start, int.end, wrapped_intervals)
    }
}

pub struct IntervalCollectionWith2DPosition {
    collection: IntervalCollection,
    pos: Point,
    rot: Rotation
}

impl IntervalCollectionWith2DPosition {
    pub fn new(collection: IntervalCollection, pos: Point, rot: Rotation) -> Self {
        Self {
            collection,
            pos,
            rot
        }
    }
}
 <commit_msg>Add full interval helper function<commit_after>use super::{Interval, IntervalEnd, IntervalCollisionObject};
use collision::Collidable;
use ::geometry::*;
use std::f64::consts::PI;

#[derive(Debug, Clone)]
pub struct IntervalCollection {
    pub start: IntervalEnd,
    pub end: IntervalEnd,
    intervals: Vec<Interval>
}

impl IntervalCollection {
    const ERRORMARGIN: f64 = 0.0001;

    pub fn new(start: IntervalEnd, end: IntervalEnd, intervals: Vec<Interval>) -> Self {
        Self {
            start,
            end,
            intervals
        }
    }

    pub fn full_interval() -> Self {
        IntervalCollection::new(
            IntervalEnd::Closed(-PI),
            IntervalEnd::Closed(PI),
            vec![Interval::new_closed(-PI, PI)])
    }

    fn relative_error_margin(&self) -> f64 {
        Self::ERRORMARGIN * (self.end.value() - self.start.value())
    }

    fn get_starts(&self) -> Vec<IntervalEnd> {
        self.intervals.iter().map(|end| { end.get_start().clone() }).collect()
    }

    fn get_ends(&self) -> Vec<IntervalEnd> {
        self.intervals.iter().map(|end| { end.get_end().clone() }).collect()
    }

    pub fn get_start_end_interval(&self) -> Interval {
        Interval::new(self.start, self.end)
    }

    pub fn invert(&self) -> IntervalCollection {
        let mut inv_intervals: Vec<Interval> = Vec::new();

        let start_included = self.start.equals(&self.intervals[0].get_start(), self.relative_error_margin());
        if !start_included {
            let first_interval = Interval::new(self.start, self.intervals[0].get_start());
            inv_intervals.push(first_interval);
        }

        for (end_prev, start_next) in self.get_ends().iter().zip(self.get_starts().iter().skip(1)) {
            inv_intervals.push(Interval::new(end_prev.clone(), start_next.clone()));
        }

        let end_included = self.end.equals(&self.intervals[0].get_end(), self.relative_error_margin());
        if !end_included {
            let last_interval = Interval::new(self.end, self.intervals[0].get_end());
            inv_intervals.push(last_interval);
        }

        IntervalCollection {
            start: self.start,
            end: self.end,
            intervals: inv_intervals
        }
    }

    pub fn contains(&self, point: f64) -> bool {
        self.intervals.iter().fold(false, |acc, int| {int.contains(point) || acc})
    }

    pub fn get_collision_objects(&self) -> Vec<IntervalCollisionObject> {
        self.intervals.iter().map(|interval| {interval.get_collision_object()} ).collect()
    }

    pub fn wrap_to_interval(&self, int: Interval) -> IntervalCollection {
        let wrapped_intervals = self.intervals.iter().flat_map(|inner_int| {int.wrap_interval_to(*inner_int)}).collect();
        Self::new(int.start, int.end, wrapped_intervals)
    }
}

pub struct IntervalCollectionWith2DPosition {
    collection: IntervalCollection,
    pos: Point,
    rot: Rotation
}

impl IntervalCollectionWith2DPosition {
    pub fn new(collection: IntervalCollection, pos: Point, rot: Rotation) -> Self {
        Self {
            collection,
            pos,
            rot
        }
    }
}
 <|endoftext|>


<commit_before>use num::Complex;

struct Pixel {
    point: Complex,
    iter: i32,
}

fn next_value(previous: f64, point: &Complex) -> f64 {
    let z = previous * previous;
    let result = z + point.abs();
    return result;
}

fn bounded(point: Complex) -> i32 {
    let mut c = 0.0;
    let mut i = 0;
    let point = point;

    while c <= 1000.0 && i <= 20 {
        i += 1;
        c = next_value(c, &point);
    }

    if c > 1000.0 {
        return i;
    } else {
        return -1;
    }
}

#[test]
fn nex_value_of_null() {
    let previous = 0.0;
    let point = Complex::new(0.0,0.0);

    assert_eq!(0.0, next_value(previous,&point));
}

#[test]
fn zero_is_bounded() {
    let point = Complex::new(0.0,0.0);

    assert_eq!(-1,bounded(point));
}

#[test]
fn unbound_is_unbound() {
    let point = Complex::new(-1.0,1.0);

    assert!(bounded(point) != -1);
}
<commit_msg>made some constants<commit_after>use num::Complex;

const MAX_VALUE: f64 = 1000.0;
const MAX_ITERATIONS: i32 = 25;

struct Pixel {
    point: Complex,
    iter: i32,
}

fn next_value(previous: f64, point: &Complex) -> f64 {
    let z = previous * previous;
    let result = z + point.abs();
    return result;
}

fn bounded(point: Complex) -> i32 {
    let mut c = 0.0;
    let mut i = 0;
    let point = point;

    while c <= MAX_VALUE && i <= MAX_ITERATIONS {
        i += 1;
        c = next_value(c, &point);
    }

    if c > 1000.0 {
        return i;
    } else {
        return -1;
    }
}

#[test]
fn nex_value_of_null() {
    let previous = 0.0;
    let point = Complex::new(0.0,0.0);

    assert_eq!(0.0, next_value(previous,&point));
}

#[test]
fn zero_is_bounded() {
    let point = Complex::new(0.0,0.0);

    assert_eq!(-1,bounded(point));
}

#[test]
fn unbound_is_unbound() {
    let point = Complex::new(-1.0,1.0);

    assert!(bounded(point) != -1);
}
<|endoftext|>


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

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0253: r##"
Attempt was made to import an unimportable value.  This can happen when
trying to import a function from a trait.  An example of this error:

```
mod foo {
    pub trait MyTrait {
        fn doSomething();
    }
}
use foo::MyTrait::doSomething;
```

In general, it's not legal to directly import functions from a crate or
concrete type.
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0403, // the name `{}` is already used
    E0404, // is not a trait
    E0405, // use of undeclared trait name
    E0406, // undeclared associated type
    E0407, // method is not a member of trait
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0417, // static variables cannot be referenced in a pattern, use a
           // `const` instead
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0424, // `self` is not available in a static method.
    E0425, // unresolved name
    E0426, // use of undeclared label
    E0427, // cannot use `ref` binding mode with ...
    E0428, // duplicate definition of ...
    E0429, // `self` imports are only allowed within a { } list
    E0430, // `self` import can only appear once in the list
    E0431, // `self` import can only appear in an import list with a non-empty
           // prefix
    E0432, // unresolved import
    E0433, // failed to resolve
    E0434, // can't capture dynamic environment in a fn item
    E0435  // attempt to use a non-constant value in a constant
}
<commit_msg>fix up crate/trait discrepancy, clarify language<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0253: r##"
Attempt was made to import an unimportable value. This can happen when
trying to import a function from a trait. An example of this error:

```
mod foo {
    pub trait MyTrait {
        fn doSomething();
    }
}
use foo::MyTrait::doSomething;
```

In general, it's not legal to directly import methods belonging to a
trait or concrete type.
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0403, // the name `{}` is already used
    E0404, // is not a trait
    E0405, // use of undeclared trait name
    E0406, // undeclared associated type
    E0407, // method is not a member of trait
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0417, // static variables cannot be referenced in a pattern, use a
           // `const` instead
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0424, // `self` is not available in a static method.
    E0425, // unresolved name
    E0426, // use of undeclared label
    E0427, // cannot use `ref` binding mode with ...
    E0428, // duplicate definition of ...
    E0429, // `self` imports are only allowed within a { } list
    E0430, // `self` import can only appear once in the list
    E0431, // `self` import can only appear in an import list with a non-empty
           // prefix
    E0432, // unresolved import
    E0433, // failed to resolve
    E0434, // can't capture dynamic environment in a fn item
    E0435  // attempt to use a non-constant value in a constant
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use crate::{
    build_project::QueryID,
    config::Config,
    config::{OperationPersister, PersistConfig},
    errors::BuildProjectError,
    Artifact, ArtifactContent,
};
use common::{sync::ParallelIterator, PerfLogEvent};
use lazy_static::lazy_static;
use log::debug;
use md5::{Digest, Md5};
use rayon::iter::IntoParallelRefMutIterator;
use regex::Regex;
use std::{fs, path::PathBuf};

lazy_static! {
    static ref RELAY_HASH_REGEX: Regex = Regex::new(r#"@relayHash (\w{32})\n"#).unwrap();
    static ref REQUEST_ID_REGEX: Regex = Regex::new(r#"@relayRequestID (.+)\n"#).unwrap();
}

pub async fn persist_operations(
    artifacts: &mut [Artifact],
    root_dir: &PathBuf,
    persist_config: &PersistConfig,
    config: &Config,
    operation_persister: &'_ (dyn OperationPersister + Send + Sync),
    log_event: &impl PerfLogEvent,
) -> Result<(), BuildProjectError> {
    let handles = artifacts
        .par_iter_mut()
        .flat_map(|artifact| {
            if let ArtifactContent::Operation {
                ref text,
                ref mut id_and_text_hash,
                ..
            } = artifact.content
            {
                let text_hash = md5(text);
                let artifact_path = root_dir.join(&artifact.path);
                let extracted_persist_id = if config.repersist_operations {
                    None
                } else {
                    extract_persist_id(&artifact_path, &text_hash)
                };
                if let Some(id) = extracted_persist_id {
                    *id_and_text_hash = Some(QueryID::Persisted { id, text_hash });
                    None
                } else {
                    let text = text.clone();
                    Some(async move {
                        operation_persister
                            .persist_artifact(text, persist_config)
                            .await
                            .map(|id| {
                                *id_and_text_hash = Some(QueryID::Persisted { id, text_hash });
                            })
                    })
                }
            } else {
                None
            }
        })
        .collect::<Vec<_>>();
    log_event.number("persist_documents", handles.len());
    log_event.number("worker_count", operation_persister.worker_count());
    let results = futures::future::join_all(handles).await;
    debug!("done persisting");
    let errors = results
        .into_iter()
        .filter_map(Result::err)
        .collect::<Vec<_>>();
    if !errors.is_empty() {
        return Err(BuildProjectError::PersistErrors { errors });
    }
    Ok(())
}

fn extract_persist_id(path: &PathBuf, text_hash: &str) -> Option<String> {
    let content = fs::read_to_string(path).ok()?;

    // Looks like a merge conflict, let's not trust this file.
    if content.contains("<<<<") || content.contains(">>>>") {
        return None;
    }

    // If the existing hash doesn't match the hash of the new query test, abort.
    if let Some(existing_hash) = extract_relay_hash(&content) {
        if existing_hash != text_hash {
            return None;
        }
    }

    extract_request_id(&content)
}

fn extract_relay_hash(content: &str) -> Option<&str> {
    RELAY_HASH_REGEX
        .captures(content)
        .and_then(|captures| captures.get(1).map(|m| m.as_str()))
}

fn extract_request_id(content: &str) -> Option<String> {
    REQUEST_ID_REGEX
        .captures(content)
        .map(|captures| captures[1].to_owned())
}

fn md5(data: &str) -> String {
    let mut md5 = Md5::new();
    md5.input(data);
    hex::encode(md5.result())
}
<commit_msg>Explicitly log persist errors<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use crate::{
    build_project::QueryID,
    config::Config,
    config::{OperationPersister, PersistConfig},
    errors::BuildProjectError,
    Artifact, ArtifactContent,
};
use common::{sync::ParallelIterator, PerfLogEvent};
use lazy_static::lazy_static;
use log::debug;
use md5::{Digest, Md5};
use rayon::iter::IntoParallelRefMutIterator;
use regex::Regex;
use std::{fs, path::PathBuf};

lazy_static! {
    static ref RELAY_HASH_REGEX: Regex = Regex::new(r#"@relayHash (\w{32})\n"#).unwrap();
    static ref REQUEST_ID_REGEX: Regex = Regex::new(r#"@relayRequestID (.+)\n"#).unwrap();
}

pub async fn persist_operations(
    artifacts: &mut [Artifact],
    root_dir: &PathBuf,
    persist_config: &PersistConfig,
    config: &Config,
    operation_persister: &'_ (dyn OperationPersister + Send + Sync),
    log_event: &impl PerfLogEvent,
) -> Result<(), BuildProjectError> {
    let handles = artifacts
        .par_iter_mut()
        .flat_map(|artifact| {
            if let ArtifactContent::Operation {
                ref text,
                ref mut id_and_text_hash,
                ..
            } = artifact.content
            {
                let text_hash = md5(text);
                let artifact_path = root_dir.join(&artifact.path);
                let extracted_persist_id = if config.repersist_operations {
                    None
                } else {
                    extract_persist_id(&artifact_path, &text_hash)
                };
                if let Some(id) = extracted_persist_id {
                    *id_and_text_hash = Some(QueryID::Persisted { id, text_hash });
                    None
                } else {
                    let text = text.clone();
                    Some(async move {
                        operation_persister
                            .persist_artifact(text, persist_config)
                            .await
                            .map(|id| {
                                *id_and_text_hash = Some(QueryID::Persisted { id, text_hash });
                            })
                    })
                }
            } else {
                None
            }
        })
        .collect::<Vec<_>>();
    log_event.number("persist_documents", handles.len());
    log_event.number("worker_count", operation_persister.worker_count());
    let results = futures::future::join_all(handles).await;
    debug!("done persisting");
    let errors = results
        .into_iter()
        .filter_map(Result::err)
        .collect::<Vec<_>>();
    if !errors.is_empty() {
        let error = BuildProjectError::PersistErrors { errors };
        log_event.string("error", error.to_string());
        return Err(error);
    }
    Ok(())
}

fn extract_persist_id(path: &PathBuf, text_hash: &str) -> Option<String> {
    let content = fs::read_to_string(path).ok()?;

    // Looks like a merge conflict, let's not trust this file.
    if content.contains("<<<<") || content.contains(">>>>") {
        return None;
    }

    // If the existing hash doesn't match the hash of the new query test, abort.
    if let Some(existing_hash) = extract_relay_hash(&content) {
        if existing_hash != text_hash {
            return None;
        }
    }

    extract_request_id(&content)
}

fn extract_relay_hash(content: &str) -> Option<&str> {
    RELAY_HASH_REGEX
        .captures(content)
        .and_then(|captures| captures.get(1).map(|m| m.as_str()))
}

fn extract_request_id(content: &str) -> Option<String> {
    REQUEST_ID_REGEX
        .captures(content)
        .map(|captures| captures[1].to_owned())
}

fn md5(data: &str) -> String {
    let mut md5 = Md5::new();
    md5.input(data);
    hex::encode(md5.result())
}
<|endoftext|>


<commit_before>/*
 * Copyright 2019 Miklos Vajna. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

extern crate atty;
extern crate reqwest;
extern crate serde_json;
extern crate url;

use std::io::Write;

type BoxResult<T> = Result<T, Box<std::error::Error>>;

#[derive(Debug)]
struct OsmifyError {
    details: String,
}

impl OsmifyError {
    fn new(msg: &str) -> OsmifyError {
        OsmifyError {
            details: msg.to_string(),
        }
    }
}

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

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

fn query_turbo(query: &str) -> BoxResult<String> {
    let url = "http://overpass-api.de/api/interpreter";

    let client = reqwest::Client::new();
    let body = String::from(query);
    let mut buf = client.post(url).body(body).send()?;
    Ok(buf.text()?)
}

fn query_nominatim(query: &str) -> BoxResult<String> {
    let prefix = "http://nominatim.openstreetmap.org/search.php?";
    let encoded: String = url::form_urlencoded::Serializer::new(String::new())
        .append_pair("q", query)
        .append_pair("format", "json")
        .finish();
    let url = format!("{}{}", prefix, encoded);

    let mut buf = reqwest::get(url.as_str())?;

    Ok(buf.text()?)
}

fn osmify(query: &str) -> BoxResult<String> {
    let nominatim = query_nominatim(query)?;
    let json: serde_json::Value = match serde_json::from_str(&nominatim) {
        Ok(value) => value,
        Err(error) => {
            return Err(Box::new(OsmifyError::new(&format!(
                "Failed to parse JSON from nominatim: {:?}",
                error
            ))));
        }
    };
    let mut elements = json.as_array().ok_or("option::NoneError")?.clone();
    if elements.is_empty() {
        return Err(Box::new(OsmifyError::new("No results from nominatim")));
    }

    if elements.len() > 1 {
        // There are multiple elements, prefer buildings if possible.
        let buildings: Vec<serde_json::Value> = elements
            .iter()
            .filter(|i| {
                let i = match i.as_object() {
                    Some(value) => value,
                    None => return false,
                };
                let class = match i.get("class") {
                    Some(value) => value.as_str(),
                    None => return false,
                };
                match class {
                    Some(value) => value == "building",
                    None => false,
                }
            })
            .cloned()
            .collect();

        if !buildings.is_empty() {
            elements = buildings;
        }
    }

    let element = elements[0].as_object().ok_or("option::NoneError")?;
    let lat = element["lat"].as_str().ok_or("no lat in json from nominatim")?;
    let lon = element["lon"].as_str().ok_or("no lon in json from nominatim")?;
    let object_type = element["osm_type"].as_str().ok_or("no osm_type in json from nominatim")?;
    let object_id = element["osm_id"].as_u64().ok_or("no osm_id in json from nominatim")?;

    // Use overpass to get the properties of the object.
    let overpass_query = format!(
        r#"[out:json];
(
    {}({});
);
out body;"#,
        object_type, object_id
    );
    let turbo = query_turbo(&overpass_query)?;
    let json: serde_json::Value = match serde_json::from_str(&turbo) {
        Ok(value) => value,
        Err(error) => {
            return Err(Box::new(OsmifyError::new(&format!(
                "Failed to parse JSON from overpass: {:?}",
                error
            ))));
        }
    };
    let json = json.as_object().ok_or("option::NoneError")?;
    let elements = &json["elements"].as_array().ok_or("option::NoneError")?;
    if elements.is_empty() {
        return Err(Box::new(OsmifyError::new("No results from overpass")));
    }

    let element = &elements[0];
    let tags = element["tags"].as_object().ok_or("option::NoneError")?;
    let city = tags["addr:city"].as_str().ok_or("option::NoneError")?;
    let housenumber = tags["addr:housenumber"]
        .as_str()
        .ok_or("option::NoneError")?;
    let postcode = tags["addr:postcode"].as_str().ok_or("option::NoneError")?;
    let street = tags["addr:street"].as_str().ok_or("option::NoneError")?;
    let addr = format!("{} {}, {} {}", postcode, city, street, housenumber);

    // Print the result.
    Ok(format!("geo:{},{} ({})", lat, lon, addr))
}

fn spinner(rx: &std::sync::mpsc::Receiver<Result<String, String>>) -> BoxResult<()> {
    let spin_characters = vec!['\\', '|', '/', '-'];
    let mut spin_index = 0;
    loop {
        match rx.try_recv() {
            Ok(result) => {
                if atty::is(atty::Stream::Stdout) {
                    print!("\r");
                }
                std::io::stdout().flush()?;
                let result = result?;
                println!("{}", result);
                return Ok(());
            }
            Err(_) => {
                if atty::is(atty::Stream::Stdout) {
                    print!("\r [{}] ", spin_characters[spin_index]);
                }
                std::io::stdout().flush()?;
                spin_index = (spin_index + 1) % spin_characters.len();
                std::thread::sleep(std::time::Duration::from_millis(100));
            }
        }
    }
}

fn main() -> BoxResult<()> {
    let args: Vec<String> = std::env::args().collect();

    if args.len() > 1 {
        let (tx, rx) = std::sync::mpsc::channel();
        std::thread::spawn(move || {
            let result = osmify(&args[1]);
            match result {
                Ok(value) => tx.send(Ok(value)),
                Err(error) => tx.send(Err(format!("Failed to osmify: {:?}", error))),
            }
        });
        spinner(&rx)?;
    } else {
        println!("usage: addr-osmify <query>");
        println!();
        println!("e.g. addr-osmify 'Mészáros utca 58/a, Budapest'");
    }

    Ok(())
}
<commit_msg>addr-osmify-rust: rustfmt<commit_after>/*
 * Copyright 2019 Miklos Vajna. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

extern crate atty;
extern crate reqwest;
extern crate serde_json;
extern crate url;

use std::io::Write;

type BoxResult<T> = Result<T, Box<std::error::Error>>;

#[derive(Debug)]
struct OsmifyError {
    details: String,
}

impl OsmifyError {
    fn new(msg: &str) -> OsmifyError {
        OsmifyError {
            details: msg.to_string(),
        }
    }
}

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

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

fn query_turbo(query: &str) -> BoxResult<String> {
    let url = "http://overpass-api.de/api/interpreter";

    let client = reqwest::Client::new();
    let body = String::from(query);
    let mut buf = client.post(url).body(body).send()?;
    Ok(buf.text()?)
}

fn query_nominatim(query: &str) -> BoxResult<String> {
    let prefix = "http://nominatim.openstreetmap.org/search.php?";
    let encoded: String = url::form_urlencoded::Serializer::new(String::new())
        .append_pair("q", query)
        .append_pair("format", "json")
        .finish();
    let url = format!("{}{}", prefix, encoded);

    let mut buf = reqwest::get(url.as_str())?;

    Ok(buf.text()?)
}

fn osmify(query: &str) -> BoxResult<String> {
    let nominatim = query_nominatim(query)?;
    let json: serde_json::Value = match serde_json::from_str(&nominatim) {
        Ok(value) => value,
        Err(error) => {
            return Err(Box::new(OsmifyError::new(&format!(
                "Failed to parse JSON from nominatim: {:?}",
                error
            ))));
        }
    };
    let mut elements = json.as_array().ok_or("option::NoneError")?.clone();
    if elements.is_empty() {
        return Err(Box::new(OsmifyError::new("No results from nominatim")));
    }

    if elements.len() > 1 {
        // There are multiple elements, prefer buildings if possible.
        let buildings: Vec<serde_json::Value> = elements
            .iter()
            .filter(|i| {
                let i = match i.as_object() {
                    Some(value) => value,
                    None => return false,
                };
                let class = match i.get("class") {
                    Some(value) => value.as_str(),
                    None => return false,
                };
                match class {
                    Some(value) => value == "building",
                    None => false,
                }
            })
            .cloned()
            .collect();

        if !buildings.is_empty() {
            elements = buildings;
        }
    }

    let element = elements[0].as_object().ok_or("option::NoneError")?;
    let lat = element["lat"]
        .as_str()
        .ok_or("no lat in json from nominatim")?;
    let lon = element["lon"]
        .as_str()
        .ok_or("no lon in json from nominatim")?;
    let object_type = element["osm_type"]
        .as_str()
        .ok_or("no osm_type in json from nominatim")?;
    let object_id = element["osm_id"]
        .as_u64()
        .ok_or("no osm_id in json from nominatim")?;

    // Use overpass to get the properties of the object.
    let overpass_query = format!(
        r#"[out:json];
(
    {}({});
);
out body;"#,
        object_type, object_id
    );
    let turbo = query_turbo(&overpass_query)?;
    let json: serde_json::Value = match serde_json::from_str(&turbo) {
        Ok(value) => value,
        Err(error) => {
            return Err(Box::new(OsmifyError::new(&format!(
                "Failed to parse JSON from overpass: {:?}",
                error
            ))));
        }
    };
    let json = json.as_object().ok_or("option::NoneError")?;
    let elements = &json["elements"].as_array().ok_or("option::NoneError")?;
    if elements.is_empty() {
        return Err(Box::new(OsmifyError::new("No results from overpass")));
    }

    let element = &elements[0];
    let tags = element["tags"].as_object().ok_or("option::NoneError")?;
    let city = tags["addr:city"].as_str().ok_or("option::NoneError")?;
    let housenumber = tags["addr:housenumber"]
        .as_str()
        .ok_or("option::NoneError")?;
    let postcode = tags["addr:postcode"].as_str().ok_or("option::NoneError")?;
    let street = tags["addr:street"].as_str().ok_or("option::NoneError")?;
    let addr = format!("{} {}, {} {}", postcode, city, street, housenumber);

    // Print the result.
    Ok(format!("geo:{},{} ({})", lat, lon, addr))
}

fn spinner(rx: &std::sync::mpsc::Receiver<Result<String, String>>) -> BoxResult<()> {
    let spin_characters = vec!['\\', '|', '/', '-'];
    let mut spin_index = 0;
    loop {
        match rx.try_recv() {
            Ok(result) => {
                if atty::is(atty::Stream::Stdout) {
                    print!("\r");
                }
                std::io::stdout().flush()?;
                let result = result?;
                println!("{}", result);
                return Ok(());
            }
            Err(_) => {
                if atty::is(atty::Stream::Stdout) {
                    print!("\r [{}] ", spin_characters[spin_index]);
                }
                std::io::stdout().flush()?;
                spin_index = (spin_index + 1) % spin_characters.len();
                std::thread::sleep(std::time::Duration::from_millis(100));
            }
        }
    }
}

fn main() -> BoxResult<()> {
    let args: Vec<String> = std::env::args().collect();

    if args.len() > 1 {
        let (tx, rx) = std::sync::mpsc::channel();
        std::thread::spawn(move || {
            let result = osmify(&args[1]);
            match result {
                Ok(value) => tx.send(Ok(value)),
                Err(error) => tx.send(Err(format!("Failed to osmify: {:?}", error))),
            }
        });
        spinner(&rx)?;
    } else {
        println!("usage: addr-osmify <query>");
        println!();
        println!("e.g. addr-osmify 'Mészáros utca 58/a, Budapest'");
    }

    Ok(())
}
<|endoftext|>


<commit_before>#![feature(arbitrary_self_types)]

use std::rc::Rc;

trait Foo {
    fn foo(self: Rc<Self>) -> usize;
}

trait Bar {
    fn foo(self: Rc<Self>) -> usize where Self: Sized;
    fn bar(self: Box<Self>) -> usize;
}

impl Foo for usize {
    fn foo(self: Rc<Self>) -> usize {
        *self
    }
}

impl Bar for usize {
    fn foo(self: Rc<Self>) -> usize {
        *self
    }

    fn bar(self: Box<Self>) -> usize {
        *self
    }
}

fn make_foo() {
    let x = Box::new(5usize) as Box<Foo>;
    //~^ ERROR E0038
    //~| NOTE method `foo` has a non-standard `self` type
    //~| NOTE the trait `Foo` cannot be made into an object
    //~| ERROR E0038
    //~| NOTE method `foo` has a non-standard `self` type
    //~| NOTE the trait `Foo` cannot be made into an object
}

fn make_bar() {
    let x = Box::new(5usize) as Box<Bar>;
    x.bar();
}

fn main() {}
<commit_msg>add a NOTE comment to the object safety test so that it passes<commit_after>#![feature(arbitrary_self_types)]

use std::rc::Rc;

trait Foo {
    fn foo(self: Rc<Self>) -> usize;
}

trait Bar {
    fn foo(self: Rc<Self>) -> usize where Self: Sized;
    fn bar(self: Box<Self>) -> usize;
}

impl Foo for usize {
    fn foo(self: Rc<Self>) -> usize {
        *self
    }
}

impl Bar for usize {
    fn foo(self: Rc<Self>) -> usize {
        *self
    }

    fn bar(self: Box<Self>) -> usize {
        *self
    }
}

fn make_foo() {
    let x = Box::new(5usize) as Box<Foo>;
    //~^ ERROR E0038
    //~| NOTE method `foo` has a non-standard `self` type
    //~| NOTE the trait `Foo` cannot be made into an object
    //~| ERROR E0038
    //~| NOTE method `foo` has a non-standard `self` type
    //~| NOTE the trait `Foo` cannot be made into an object
    //~| NOTE required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<Foo>>` for `std::boxed::Box<usize>`
}

fn make_bar() {
    let x = Box::new(5usize) as Box<Bar>;
    x.bar();
}

fn main() {}
<|endoftext|>


<commit_before>/*!
`SipHash-2-4`

*/
use libc::{c_ulonglong, c_int};
use randombytes::randombytes_into;

#[link(name = "sodium")]
extern {
    fn crypto_shorthash_siphash24(h: *mut u8,
                                  m: *u8,
                                  mlen: c_ulonglong,
                                  k: *u8) -> c_int;
}

pub static HASHBYTES: uint = 8;
pub static KEYBYTES: uint = 16;

/**
 * Digest-structure
 */
pub struct Digest([u8, ..HASHBYTES]);

/**
 * Key
 *
 * When a `Key` goes out of scope its contents
 * will be zeroed out
 */
pub struct Key([u8, ..KEYBYTES]);

impl Drop for Key {
    fn drop(&mut self) {
        let &Key(ref mut k) = self;
        for e in k.mut_iter() { *e = 0 }
    }
}

/**
 * `gen_key()` randomly generates a key for shorthash
 *
 * THREAD SAFETY: `gen_key()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_key() -> Key {
    let mut k = [0, ..KEYBYTES];
    randombytes_into(k);
    Key(k)
}

/**
 * `shorthash` hashes a message `m` under a key `k`. It
 * returns a hash `h`.
 */
pub fn shorthash(m: &[u8],
                 &Key(k): &Key) -> Digest {
    unsafe {
        let mut h = [0, ..HASHBYTES];
        crypto_shorthash_siphash24(h.as_mut_ptr(),
                                   m.as_ptr(), m.len() as c_ulonglong,
                                   k.as_ptr());
        Digest(h)
    }
}

#[test]
fn test_vectors() {
    use std::slice::with_capacity;
    let maxlen = 64;
    let mut m = with_capacity(64);
    for i in range(0, 64) {
        m.push(i as u8);
    }
    let h_expecteds = [[0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72]
                      ,[0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74]
                      ,[0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d]
                      ,[0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85]
                      ,[0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf]
                      ,[0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18]
                      ,[0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb]
                      ,[0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab]
                      ,[0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93]
                      ,[0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e]
                      ,[0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a]
                      ,[0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4]
                      ,[0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75]
                      ,[0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14]
                      ,[0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7]
                      ,[0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1]
                      ,[0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f]
                      ,[0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69]
                      ,[0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b]
                      ,[0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb]
                      ,[0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe]
                      ,[0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0]
                      ,[0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93]
                      ,[0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8]
                      ,[0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8]
                      ,[0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc]
                      ,[0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17]
                      ,[0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f]
                      ,[0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde]
                      ,[0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6]
                      ,[0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad]
                      ,[0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32]
                      ,[0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71]
                      ,[0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7]
                      ,[0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12]
                      ,[0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15]
                      ,[0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31]
                      ,[0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02]
                      ,[0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca]
                      ,[0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a]
                      ,[0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e]
                      ,[0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad]
                      ,[0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18]
                      ,[0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4]
                      ,[0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9]
                      ,[0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9]
                      ,[0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb]
                      ,[0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0]
                      ,[0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6]
                      ,[0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7]
                      ,[0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee]
                      ,[0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1]
                      ,[0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a]
                      ,[0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81]
                      ,[0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f]
                      ,[0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24]
                      ,[0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7]
                      ,[0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea]
                      ,[0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60]
                      ,[0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66]
                      ,[0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c]
                      ,[0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f]
                      ,[0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5]
                      ,[0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95]];
    let k = Key([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
    for i in range(0, maxlen) {
        let Digest(h) = shorthash(m.slice(0, i as uint), &k);
        assert!(h == h_expecteds[i]);
    }
}
<commit_msg>Array indexes are unsigned now<commit_after>/*!
`SipHash-2-4`

*/
use libc::{c_ulonglong, c_int};
use randombytes::randombytes_into;

#[link(name = "sodium")]
extern {
    fn crypto_shorthash_siphash24(h: *mut u8,
                                  m: *u8,
                                  mlen: c_ulonglong,
                                  k: *u8) -> c_int;
}

pub static HASHBYTES: uint = 8;
pub static KEYBYTES: uint = 16;

/**
 * Digest-structure
 */
pub struct Digest([u8, ..HASHBYTES]);

/**
 * Key
 *
 * When a `Key` goes out of scope its contents
 * will be zeroed out
 */
pub struct Key([u8, ..KEYBYTES]);

impl Drop for Key {
    fn drop(&mut self) {
        let &Key(ref mut k) = self;
        for e in k.mut_iter() { *e = 0 }
    }
}

/**
 * `gen_key()` randomly generates a key for shorthash
 *
 * THREAD SAFETY: `gen_key()` is thread-safe provided that you have
 * called `sodiumoxide::init()` once before using any other function
 * from sodiumoxide.
 */
pub fn gen_key() -> Key {
    let mut k = [0, ..KEYBYTES];
    randombytes_into(k);
    Key(k)
}

/**
 * `shorthash` hashes a message `m` under a key `k`. It
 * returns a hash `h`.
 */
pub fn shorthash(m: &[u8],
                 &Key(k): &Key) -> Digest {
    unsafe {
        let mut h = [0, ..HASHBYTES];
        crypto_shorthash_siphash24(h.as_mut_ptr(),
                                   m.as_ptr(), m.len() as c_ulonglong,
                                   k.as_ptr());
        Digest(h)
    }
}

#[test]
fn test_vectors() {
    use std::slice::with_capacity;
    let maxlen = 64;
    let mut m = with_capacity(64);
    for i in range(0, 64) {
        m.push(i as u8);
    }
    let h_expecteds = [[0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72]
                      ,[0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74]
                      ,[0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d]
                      ,[0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85]
                      ,[0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf]
                      ,[0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18]
                      ,[0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb]
                      ,[0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab]
                      ,[0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93]
                      ,[0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e]
                      ,[0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a]
                      ,[0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4]
                      ,[0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75]
                      ,[0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14]
                      ,[0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7]
                      ,[0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1]
                      ,[0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f]
                      ,[0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69]
                      ,[0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b]
                      ,[0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb]
                      ,[0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe]
                      ,[0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0]
                      ,[0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93]
                      ,[0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8]
                      ,[0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8]
                      ,[0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc]
                      ,[0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17]
                      ,[0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f]
                      ,[0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde]
                      ,[0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6]
                      ,[0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad]
                      ,[0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32]
                      ,[0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71]
                      ,[0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7]
                      ,[0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12]
                      ,[0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15]
                      ,[0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31]
                      ,[0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02]
                      ,[0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca]
                      ,[0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a]
                      ,[0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e]
                      ,[0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad]
                      ,[0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18]
                      ,[0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4]
                      ,[0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9]
                      ,[0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9]
                      ,[0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb]
                      ,[0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0]
                      ,[0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6]
                      ,[0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7]
                      ,[0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee]
                      ,[0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1]
                      ,[0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a]
                      ,[0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81]
                      ,[0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f]
                      ,[0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24]
                      ,[0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7]
                      ,[0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea]
                      ,[0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60]
                      ,[0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66]
                      ,[0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c]
                      ,[0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f]
                      ,[0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5]
                      ,[0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95]];
    let k = Key([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
    for i in range(0u, maxlen) {
        let Digest(h) = shorthash(m.slice(0, i), &k);
        assert!(h == h_expecteds[i]);
    }
}
<|endoftext|>


<commit_before>struct HTMLImageData {
    mut image: Option<~str>
}

struct ElementData {
    kind: ~ElementKind
}

enum ElementKind {
    HTMLImageElement(HTMLImageData)
}

enum NodeKind {
    Element(ElementData)
}

enum NodeData = {
    kind: ~NodeKind
};

fn main() {
    let id = HTMLImageData { image: None };
    let ed = ElementData { kind: ~HTMLImageElement(id) };
    let n = NodeData({kind : ~Element(ed)});
    match n.kind {
        ~Element(ed) => match ed.kind {
            ~HTMLImageElement(d) if d.image.is_some() => { true }
        },
        _ => fail ~"WAT" //~ ERROR wat
    };
}
<commit_msg>Actually xfail this, unbreak build<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-test
struct HTMLImageData {
    mut image: Option<~str>
}

struct ElementData {
    kind: ~ElementKind
}

enum ElementKind {
    HTMLImageElement(HTMLImageData)
}

enum NodeKind {
    Element(ElementData)
}

enum NodeData = {
    kind: ~NodeKind
};

fn main() {
    let id = HTMLImageData { image: None };
    let ed = ElementData { kind: ~HTMLImageElement(id) };
    let n = NodeData({kind : ~Element(ed)});
    match n.kind {
        ~Element(ed) => match ed.kind {
            ~HTMLImageElement(d) if d.image.is_some() => { true }
        },
        _ => fail ~"WAT" //~ ERROR wat
    };
}
<|endoftext|>


<commit_before>use kay::{Recipient, Fate, ActorSystem};
use descartes::{Band, Path, FiniteCurve};
use monet::{Thing, Instance};
use ::core::geometry::band_to_thing;
use super::{CurrentPlan, LaneStroke, DrawingStatus, SelectableStrokeRef};

use monet::SetupInScene;

impl Recipient<SetupInScene> for CurrentPlan {
    fn receive(&mut self, _msg: &SetupInScene) -> Fate {
        Fate::Live
    }
}

use monet::RenderToScene;
use monet::UpdateThing;

impl Recipient<RenderToScene> for CurrentPlan {
    fn receive(&mut self, msg: &RenderToScene) -> Fate {match *msg{
        RenderToScene{renderer_id, scene_id} => {
            if self.preview.ui_state.dirty {
                let stroke_thing : Thing = self.preview.delta.new_strokes.iter()
                    .filter(|stroke| stroke.nodes().len() > 1)
                    .map(LaneStroke::preview_thing)
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 499,
                    thing: stroke_thing,
                    instance: Instance::with_color([0.8, 0.8, 0.8])
                };
                let trimmed_stroke_thing : Thing = self.preview.current_plan_result_delta.trimmed_strokes.to_create.values()
                    .filter(|stroke| stroke.nodes().len() > 1)
                    .map(LaneStroke::preview_thing)
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 500,
                    thing: trimmed_stroke_thing,
                    instance: Instance::with_color([0.3, 0.3, 0.5])
                };
                let intersections_thing : Thing = self.preview.current_plan_result_delta.intersections.to_create.values()
                    .filter(|i| i.shape.segments().len() > 0)
                    .map(|i| band_to_thing(&Band::new(i.shape.clone(), 0.4), 0.5))
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 501,
                    thing: intersections_thing,
                    instance: Instance::with_color([0.0, 0.0, 1.0])
                };
                let connecting_strokes_thing : Thing = self.preview.current_plan_result_delta.intersections.to_create.values()
                    .filter(|i| !i.strokes.is_empty())
                    .map(|i| -> Thing {i.strokes.iter().map(LaneStroke::preview_thing).sum()})
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 502,
                    thing: connecting_strokes_thing,
                    instance: Instance::with_color([0.5, 0.5, 1.0])
                };
                let transfer_strokes_thing : Thing = self.preview.current_plan_result_delta.transfer_strokes.to_create.values()
                    .map(|lane_stroke|
                        band_to_thing(&Band::new(lane_stroke.path().clone(), 0.3), 0.1))
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 503,
                    thing: transfer_strokes_thing,
                    instance: Instance::with_color([1.0, 0.5, 0.0])
                };
                self.preview.ui_state.dirty = false;
            }
            if let DrawingStatus::WithSelections(ref selections, _) = self.preview.ui_state.drawing_status {
                let selection_thing = selections.pairs().filter_map(|(&selection_ref, &(start, end))| {
                    let stroke = match selection_ref {
                        SelectableStrokeRef::New(stroke_idx) => &self.preview.delta.new_strokes[stroke_idx],
                        SelectableStrokeRef::RemainingOld(old_stroke_ref) => self.preview.current_remaining_old_strokes.mapping.get(old_stroke_ref).unwrap()
                    };
                    stroke.path().subsection(start, end).map(|subsection|
                        band_to_thing(&Band::new(subsection, 5.0), 0.1)
                    )
                }).sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 504,
                    thing: selection_thing,
                    instance: Instance::with_color([0.0, 0.0, 1.0])
                };
            } else {
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 504,
                    thing: Thing::new(vec![], vec![]),
                    instance: Instance::with_color([0.0, 0.0, 1.0])
                };
            }
            Fate::Live
        }
    }}
}

pub fn setup(system: &mut ActorSystem) {
    system.add_inbox::<SetupInScene, CurrentPlan>();
    system.add_inbox::<RenderToScene, CurrentPlan>();
}<commit_msg>Representation of lanes to be destroyed in planning mode #12<commit_after>use kay::{Recipient, Fate, ActorSystem};
use descartes::{Band, Path, FiniteCurve};
use monet::{Thing, Instance};
use ::core::geometry::band_to_thing;
use super::{CurrentPlan, LaneStroke, DrawingStatus, SelectableStrokeRef};

use monet::SetupInScene;

impl Recipient<SetupInScene> for CurrentPlan {
    fn receive(&mut self, _msg: &SetupInScene) -> Fate {
        Fate::Live
    }
}

use monet::RenderToScene;
use monet::UpdateThing;

impl Recipient<RenderToScene> for CurrentPlan {
    fn receive(&mut self, msg: &RenderToScene) -> Fate {match *msg{
        RenderToScene{renderer_id, scene_id} => {
            if self.preview.ui_state.dirty {
                let changed_old_stroke_thing : Thing = self.preview.delta.strokes_to_destroy.values()
                    .filter(|stroke| stroke.nodes().len() > 1)
                    .map(LaneStroke::preview_thing)
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 498,
                    thing: changed_old_stroke_thing,
                    instance: Instance::with_color([1.0, 0.4, 0.4])
                };
                let stroke_thing : Thing = self.preview.delta.new_strokes.iter()
                    .filter(|stroke| stroke.nodes().len() > 1)
                    .map(LaneStroke::preview_thing)
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 499,
                    thing: stroke_thing,
                    instance: Instance::with_color([0.8, 0.8, 0.8])
                };
                let trimmed_stroke_thing : Thing = self.preview.current_plan_result_delta.trimmed_strokes.to_create.values()
                    .filter(|stroke| stroke.nodes().len() > 1)
                    .map(LaneStroke::preview_thing)
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 500,
                    thing: trimmed_stroke_thing,
                    instance: Instance::with_color([0.3, 0.3, 0.5])
                };
                let intersections_thing : Thing = self.preview.current_plan_result_delta.intersections.to_create.values()
                    .filter(|i| i.shape.segments().len() > 0)
                    .map(|i| band_to_thing(&Band::new(i.shape.clone(), 0.4), 0.5))
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 501,
                    thing: intersections_thing,
                    instance: Instance::with_color([0.0, 0.0, 1.0])
                };
                let connecting_strokes_thing : Thing = self.preview.current_plan_result_delta.intersections.to_create.values()
                    .filter(|i| !i.strokes.is_empty())
                    .map(|i| -> Thing {i.strokes.iter().map(LaneStroke::preview_thing).sum()})
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 502,
                    thing: connecting_strokes_thing,
                    instance: Instance::with_color([0.5, 0.5, 1.0])
                };
                let transfer_strokes_thing : Thing = self.preview.current_plan_result_delta.transfer_strokes.to_create.values()
                    .map(|lane_stroke|
                        band_to_thing(&Band::new(lane_stroke.path().clone(), 0.3), 0.1))
                    .sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 503,
                    thing: transfer_strokes_thing,
                    instance: Instance::with_color([1.0, 0.5, 0.0])
                };
                self.preview.ui_state.dirty = false;
            }
            if let DrawingStatus::WithSelections(ref selections, _) = self.preview.ui_state.drawing_status {
                let selection_thing = selections.pairs().filter_map(|(&selection_ref, &(start, end))| {
                    let stroke = match selection_ref {
                        SelectableStrokeRef::New(stroke_idx) => &self.preview.delta.new_strokes[stroke_idx],
                        SelectableStrokeRef::RemainingOld(old_stroke_ref) => self.preview.current_remaining_old_strokes.mapping.get(old_stroke_ref).unwrap()
                    };
                    stroke.path().subsection(start, end).map(|subsection|
                        band_to_thing(&Band::new(subsection, 5.0), 0.1)
                    )
                }).sum();
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 504,
                    thing: selection_thing,
                    instance: Instance::with_color([0.0, 0.0, 1.0])
                };
            } else {
                renderer_id << UpdateThing{
                    scene_id: scene_id,
                    thing_id: 504,
                    thing: Thing::new(vec![], vec![]),
                    instance: Instance::with_color([0.0, 0.0, 1.0])
                };
            }
            Fate::Live
        }
    }}
}

pub fn setup(system: &mut ActorSystem) {
    system.add_inbox::<SetupInScene, CurrentPlan>();
    system.add_inbox::<RenderToScene, CurrentPlan>();
}<|endoftext|>