<commit_before>use bitflags::__impl_bitflags;
use serde::{
    de::{Deserialize, Deserializer},
    ser::{Serialize, Serializer},
};

/// [Gateway Intents] will limit the events your bot will receive via the gateway.
/// By default, all intents except [Privileged Intents] are selected.
///
/// # What are Intents
///
/// A [gateway intent] sets the types of gateway events
/// (e.g. member joins, guild integrations, guild emoji updates, ...) the
/// bot shall receive. Carefully picking the needed intents greatly helps
/// the bot to scale, as less intents will result in less events to be
/// received via the network from Discord and less processing needed for
/// handling the data.
///
/// # Privileged Intents
///
/// The intents [`GatewayIntents::GUILD_PRESENCES`] and [`GatewayIntents::GUILD_MEMBERS`]
/// are [Privileged Intents]. They need to be enabled in the
/// *developer portal*.
///
/// **Note**:
/// Once the bot is in 100 guilds or more, [the bot must be verified] in
/// order to use privileged intents.
///
/// [gateway intent]: https://discord.com/developers/docs/topics/gateway#privileged-intents
/// [Privileged Intents]: https://discord.com/developers/docs/topics/gateway#privileged-intents
/// [the bot must be verified]: https://support.discord.com/hc/en-us/articles/360040720412-Bot-Verification-and-Data-Whitelisting
/// [`GatewayIntents::GuildPresences`]: serenity::client::bridge::gateway::GatewayIntents::GUILD_PRESENCES
/// [`GatewayIntents::GuildMembers`]: serenity::client::bridge::gateway::GatewayIntents::GUILD_MEMBERS
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
pub struct GatewayIntents {
    /// The flags composing gateway intents.
    ///
    /// # Note
    /// Do not modify this yourself; use the provided methods.
    /// Do the same when creating, unless you're absolutely certain that you're giving valid intents flags.
    pub bits: u64,
}

__impl_bitflags! {
    GatewayIntents: u64 {
        /// Enables following gateway events:
        ///
        /// - GUILD_CREATE
        /// - GUILD_DELETE
        /// - GUILD_ROLE_CREATE
        /// - GUILD_ROLE_UPDATE
        /// - GUILD_ROLE_DELETE
        /// - CHANNEL_CREATE
        /// - CHANNEL_UPDATE
        /// - CHANNEL_DELETE
        /// - CHANNEL_PINS_UPDATE
        /// - THREAD_CREATE
        /// - THREAD_UPDATE
        /// - THREAD_DELETE
        /// - THREAD_LIST_SYNC
        /// - THREAD_MEMBER_UPDATE
        /// - THREAD_MEMBERS_UPDATE
        /// - STAGE_INSTANCE_CREATE
        /// - STAGE_INSTANCE_UPDATE
        /// - STAGE_INSTANCE_DELETE
        GUILDS = 1;
        /// Enables following gateway events:
        ///
        /// - GUILD_MEMBER_ADD
        /// - GUILD_MEMBER_UPDATE
        /// - GUILD_MEMBER_REMOVE
        /// - THREAD_MEMBERS_UPDATE
        ///
        /// **Info**:
        /// This intent is *privileged*.
        /// In order to use it, you must head to your application in the
        /// Developer Portal and enable the toggle for *Privileged Intents*.
        ///
        /// This intent is also necessary to even receive the events in contains.
        GUILD_MEMBERS = 1 << 1;
        /// Enables following gateway events:
        ///
        /// - GUILD_BAN_ADD
        /// - GUILD_BAN_REMOVE
        GUILD_BANS = 1 << 2;
        /// Enables following gateway event:
        ///
        /// - GUILD_EMOJIS_UPDATE
        GUILD_EMOJIS = 1 << 3;
        /// Enables following gateway event:
        ///
        /// - GUILD_INTEGRATIONS_UPDATE
        /// - INTEGRATION_CREATE
        /// - INTEGRATION_UPDATE
        /// - INTEGRATION_DELETE
        GUILD_INTEGRATIONS = 1 << 4;
        /// Enables following gateway event:
        ///
        /// - WEBHOOKS_UPDATE
        GUILD_WEBHOOKS = 1 << 5;
        /// Enables following gateway events:
        ///
        /// - INVITE_CREATE
        /// - INVITE_DELETE
        GUILD_INVITES = 1 << 6;
        /// Enables following gateway event:
        ///
        /// - VOICE_STATE_UPDATE
        GUILD_VOICE_STATES = 1 << 7;
        /// Enables following gateway event:
        ///
        /// - PRESENCE_UPDATE
        ///
        /// **Info**:
        /// This intent is *privileged*.
        /// In order to use it, you must head to your application in the
        /// Developer Portal and enable the toggle for *Privileged Intents*.
        ///
        /// This intent is also necessary to even receive the events in contains.
        GUILD_PRESENCES = 1 << 8;
        /// Enables following gateway events:
        ///
        /// - MESSAGE_CREATE
        /// - MESSAGE_UPDATE
        /// - MESSAGE_DELETE
        /// - MESSAGE_DELETE_BULK
        GUILD_MESSAGES = 1 << 9;
        /// Enables following gateway events:
        ///
        /// - MESSAGE_REACTION_ADD
        /// - MESSAGE_REACTION_REMOVE
        /// - MESSAGE_REACTION_REMOVE_ALL
        /// - MESSAGE_REACTION_REMOVE_EMOJI
        GUILD_MESSAGE_REACTIONS = 1 << 10;
        /// Enable following gateway event:
        ///
        /// - TYPING_START
        GUILD_MESSAGE_TYPING = 1 << 11;
        /// Enable following gateway events:
        ///
        /// - MESSAGE_CREATE
        /// - MESSAGE_UPDATE
        /// - MESSAGE_DELETE
        /// - CHANNEL_PINS_UPDATE
        DIRECT_MESSAGES = 1 << 12;
        /// Enable following gateway events:
        ///
        /// - MESSAGE_REACTION_ADD
        /// - MESSAGE_REACTION_REMOVE
        /// - MESSAGE_REACTION_REMOVE_ALL
        /// - MESSAGE_REACTION_REMOVE_EMOJI
        DIRECT_MESSAGE_REACTIONS = 1 << 13;
        /// Enable following gateway event:
        ///
        /// - TYPING_START
        DIRECT_MESSAGE_TYPING = 1 << 14;
        /// Enable following gateway events:
        ///
        /// - GUILD_SCHEDULED_EVENT_CREATE
        /// - GUILD_SCHEDULED_EVENT_UPDATE
        /// - GUILD_SCHEDULED_EVENT_DELETE
        /// - GUILD_SCHEDULED_EVENT_USER_ADD
        /// - GUILD_SCHEDULED_EVENT_USER_REMOVE
        GUILD_SCHEDULED_EVENTS = 1 << 16;
    }
}

impl Default for GatewayIntents {
    fn default() -> Self {
        Self::empty()
    }
}

impl<'de> Deserialize<'de> for GatewayIntents {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?))
    }
}

impl Serialize for GatewayIntents {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_u64(self.bits())
    }
}

#[cfg(feature = "model")]
impl GatewayIntents {
    /// Gets all of the intents that don't are considered privileged by Discord.
    pub const fn non_privileged() -> GatewayIntents {
        // bitflags don't support const evaluation. Workaround.
        // See: https://github.com/bitflags/bitflags/issues/180
        Self::from_bits_truncate(Self::all().bits() & !Self::privileged().bits())
    }

    /// Gets all of the intents that are considered privileged by Discord.
    /// Use of these intents will require explicitly whitelisting the bot.
    pub const fn privileged() -> GatewayIntents {
        // bitflags don't support const evaluation. Workaround.
        // See: https://github.com/bitflags/bitflags/issues/180
        Self::from_bits_truncate(Self::GUILD_MEMBERS.bits() | Self::GUILD_PRESENCES.bits())
    }

    /// Checks if any of the included intents are privileged
    ///
    /// [GUILD_MEMBERS]: #associatedconstant.GUILD_MEMBERS
    /// [GUILD_PRESENCES]: #associatedconstant.GUILD_PRESENCES
    pub fn is_privileged(self) -> bool {
        self.guild_members() || self.guild_presences()
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILDS] intent.
    ///
    /// [GUILDS]: Self::GUILDS
    pub fn guilds(self) -> bool {
        self.contains(Self::GUILDS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_MEMBERS] intent.
    ///
    /// [GUILD_MEMBERS]: Self::GUILD_MEMBERS
    pub fn guild_members(self) -> bool {
        self.contains(Self::GUILD_MEMBERS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_BANS] intent.
    ///
    /// [GUILD_BANS]: Self::GUILD_BANS
    pub fn guild_bans(self) -> bool {
        self.contains(Self::GUILD_BANS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_EMOJIS] intent.
    ///
    /// [GUILD_EMOJIS]: Self::GUILD_EMOJIS
    pub fn guild_emojis(self) -> bool {
        self.contains(Self::GUILD_EMOJIS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_INTEGRATIONS] intent.
    ///
    /// [GUILD_INTEGRATIONS]: Self::GUILD_INTEGRATIONS
    pub fn guild_integrations(self) -> bool {
        self.contains(Self::GUILD_INTEGRATIONS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_WEBHOOKS] intent.
    ///
    /// [GUILD_WEBHOOKS]: Self::GUILD_WEBHOOKS
    pub fn guild_webhooks(self) -> bool {
        self.contains(Self::GUILD_WEBHOOKS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_INVITES] intent.
    ///
    /// [GUILD_INVITES]: Self::GUILD_INVITES
    pub fn guild_invites(self) -> bool {
        self.contains(Self::GUILD_INVITES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_VOICE_STATES] intent.
    ///
    /// [GUILD_VOICE_STATES]: Self::GUILD_VOICE_STATES
    pub fn guild_voice_states(self) -> bool {
        self.contains(Self::GUILD_VOICE_STATES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_PRESENCES] intent.
    ///
    /// [GUILD_PRESENCES]: Self::GUILD_PRESENCES
    pub fn guild_presences(self) -> bool {
        self.contains(Self::GUILD_PRESENCES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_MESSAGE_REACTIONS] intent.
    ///
    /// [GUILD_MESSAGE_REACTIONS]: Self::GUILD_MESSAGE_REACTIONS
    pub fn guild_message_reactions(self) -> bool {
        self.contains(Self::GUILD_MESSAGE_REACTIONS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_MESSAGE_TYPING] intent.
    ///
    /// [GUILD_MESSAGE_TYPING]: Self::GUILD_MESSAGE_TYPING
    pub fn guild_message_typing(self) -> bool {
        self.contains(Self::GUILD_MESSAGE_TYPING)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [DIRECT_MESSAGES] intent.
    ///
    /// [DIRECT_MESSAGES]: Self::DIRECT_MESSAGES
    pub fn direct_messages(self) -> bool {
        self.contains(Self::DIRECT_MESSAGES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [DIRECT_MESSAGE_REACTIONS] intent.
    ///
    /// [DIRECT_MESSAGE_REACTIONS]: Self::DIRECT_MESSAGE_REACTIONS
    pub fn direct_message_reactions(self) -> bool {
        self.contains(Self::DIRECT_MESSAGE_REACTIONS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [DIRECT_MESSAGE_TYPING] intent.
    ///
    /// [DIRECT_MESSAGE_TYPING]: Self::DIRECT_MESSAGE_TYPING
    pub fn direct_message_typing(self) -> bool {
        self.contains(Self::DIRECT_MESSAGE_TYPING)
    }
}
<commit_msg>Add shorthand for checking the `GUILD_MESSAGES` intent bitflag (#1786)<commit_after>use bitflags::__impl_bitflags;
use serde::{
    de::{Deserialize, Deserializer},
    ser::{Serialize, Serializer},
};

/// [Gateway Intents] will limit the events your bot will receive via the gateway.
/// By default, all intents except [Privileged Intents] are selected.
///
/// # What are Intents
///
/// A [gateway intent] sets the types of gateway events
/// (e.g. member joins, guild integrations, guild emoji updates, ...) the
/// bot shall receive. Carefully picking the needed intents greatly helps
/// the bot to scale, as less intents will result in less events to be
/// received via the network from Discord and less processing needed for
/// handling the data.
///
/// # Privileged Intents
///
/// The intents [`GatewayIntents::GUILD_PRESENCES`] and [`GatewayIntents::GUILD_MEMBERS`]
/// are [Privileged Intents]. They need to be enabled in the
/// *developer portal*.
///
/// **Note**:
/// Once the bot is in 100 guilds or more, [the bot must be verified] in
/// order to use privileged intents.
///
/// [gateway intent]: https://discord.com/developers/docs/topics/gateway#privileged-intents
/// [Privileged Intents]: https://discord.com/developers/docs/topics/gateway#privileged-intents
/// [the bot must be verified]: https://support.discord.com/hc/en-us/articles/360040720412-Bot-Verification-and-Data-Whitelisting
/// [`GatewayIntents::GuildPresences`]: serenity::client::bridge::gateway::GatewayIntents::GUILD_PRESENCES
/// [`GatewayIntents::GuildMembers`]: serenity::client::bridge::gateway::GatewayIntents::GUILD_MEMBERS
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
pub struct GatewayIntents {
    /// The flags composing gateway intents.
    ///
    /// # Note
    /// Do not modify this yourself; use the provided methods.
    /// Do the same when creating, unless you're absolutely certain that you're giving valid intents flags.
    pub bits: u64,
}

__impl_bitflags! {
    GatewayIntents: u64 {
        /// Enables following gateway events:
        ///
        /// - GUILD_CREATE
        /// - GUILD_DELETE
        /// - GUILD_ROLE_CREATE
        /// - GUILD_ROLE_UPDATE
        /// - GUILD_ROLE_DELETE
        /// - CHANNEL_CREATE
        /// - CHANNEL_UPDATE
        /// - CHANNEL_DELETE
        /// - CHANNEL_PINS_UPDATE
        /// - THREAD_CREATE
        /// - THREAD_UPDATE
        /// - THREAD_DELETE
        /// - THREAD_LIST_SYNC
        /// - THREAD_MEMBER_UPDATE
        /// - THREAD_MEMBERS_UPDATE
        /// - STAGE_INSTANCE_CREATE
        /// - STAGE_INSTANCE_UPDATE
        /// - STAGE_INSTANCE_DELETE
        GUILDS = 1;
        /// Enables following gateway events:
        ///
        /// - GUILD_MEMBER_ADD
        /// - GUILD_MEMBER_UPDATE
        /// - GUILD_MEMBER_REMOVE
        /// - THREAD_MEMBERS_UPDATE
        ///
        /// **Info**:
        /// This intent is *privileged*.
        /// In order to use it, you must head to your application in the
        /// Developer Portal and enable the toggle for *Privileged Intents*.
        ///
        /// This intent is also necessary to even receive the events in contains.
        GUILD_MEMBERS = 1 << 1;
        /// Enables following gateway events:
        ///
        /// - GUILD_BAN_ADD
        /// - GUILD_BAN_REMOVE
        GUILD_BANS = 1 << 2;
        /// Enables following gateway event:
        ///
        /// - GUILD_EMOJIS_UPDATE
        GUILD_EMOJIS = 1 << 3;
        /// Enables following gateway event:
        ///
        /// - GUILD_INTEGRATIONS_UPDATE
        /// - INTEGRATION_CREATE
        /// - INTEGRATION_UPDATE
        /// - INTEGRATION_DELETE
        GUILD_INTEGRATIONS = 1 << 4;
        /// Enables following gateway event:
        ///
        /// - WEBHOOKS_UPDATE
        GUILD_WEBHOOKS = 1 << 5;
        /// Enables following gateway events:
        ///
        /// - INVITE_CREATE
        /// - INVITE_DELETE
        GUILD_INVITES = 1 << 6;
        /// Enables following gateway event:
        ///
        /// - VOICE_STATE_UPDATE
        GUILD_VOICE_STATES = 1 << 7;
        /// Enables following gateway event:
        ///
        /// - PRESENCE_UPDATE
        ///
        /// **Info**:
        /// This intent is *privileged*.
        /// In order to use it, you must head to your application in the
        /// Developer Portal and enable the toggle for *Privileged Intents*.
        ///
        /// This intent is also necessary to even receive the events in contains.
        GUILD_PRESENCES = 1 << 8;
        /// Enables following gateway events:
        ///
        /// - MESSAGE_CREATE
        /// - MESSAGE_UPDATE
        /// - MESSAGE_DELETE
        /// - MESSAGE_DELETE_BULK
        GUILD_MESSAGES = 1 << 9;
        /// Enables following gateway events:
        ///
        /// - MESSAGE_REACTION_ADD
        /// - MESSAGE_REACTION_REMOVE
        /// - MESSAGE_REACTION_REMOVE_ALL
        /// - MESSAGE_REACTION_REMOVE_EMOJI
        GUILD_MESSAGE_REACTIONS = 1 << 10;
        /// Enable following gateway event:
        ///
        /// - TYPING_START
        GUILD_MESSAGE_TYPING = 1 << 11;
        /// Enable following gateway events:
        ///
        /// - MESSAGE_CREATE
        /// - MESSAGE_UPDATE
        /// - MESSAGE_DELETE
        /// - CHANNEL_PINS_UPDATE
        DIRECT_MESSAGES = 1 << 12;
        /// Enable following gateway events:
        ///
        /// - MESSAGE_REACTION_ADD
        /// - MESSAGE_REACTION_REMOVE
        /// - MESSAGE_REACTION_REMOVE_ALL
        /// - MESSAGE_REACTION_REMOVE_EMOJI
        DIRECT_MESSAGE_REACTIONS = 1 << 13;
        /// Enable following gateway event:
        ///
        /// - TYPING_START
        DIRECT_MESSAGE_TYPING = 1 << 14;
        /// Enable following gateway events:
        ///
        /// - GUILD_SCHEDULED_EVENT_CREATE
        /// - GUILD_SCHEDULED_EVENT_UPDATE
        /// - GUILD_SCHEDULED_EVENT_DELETE
        /// - GUILD_SCHEDULED_EVENT_USER_ADD
        /// - GUILD_SCHEDULED_EVENT_USER_REMOVE
        GUILD_SCHEDULED_EVENTS = 1 << 16;
    }
}

impl Default for GatewayIntents {
    fn default() -> Self {
        Self::empty()
    }
}

impl<'de> Deserialize<'de> for GatewayIntents {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?))
    }
}

impl Serialize for GatewayIntents {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_u64(self.bits())
    }
}

#[cfg(feature = "model")]
impl GatewayIntents {
    /// Gets all of the intents that don't are considered privileged by Discord.
    pub const fn non_privileged() -> GatewayIntents {
        // bitflags don't support const evaluation. Workaround.
        // See: https://github.com/bitflags/bitflags/issues/180
        Self::from_bits_truncate(Self::all().bits() & !Self::privileged().bits())
    }

    /// Gets all of the intents that are considered privileged by Discord.
    /// Use of these intents will require explicitly whitelisting the bot.
    pub const fn privileged() -> GatewayIntents {
        // bitflags don't support const evaluation. Workaround.
        // See: https://github.com/bitflags/bitflags/issues/180
        Self::from_bits_truncate(Self::GUILD_MEMBERS.bits() | Self::GUILD_PRESENCES.bits())
    }

    /// Checks if any of the included intents are privileged
    ///
    /// [GUILD_MEMBERS]: #associatedconstant.GUILD_MEMBERS
    /// [GUILD_PRESENCES]: #associatedconstant.GUILD_PRESENCES
    pub fn is_privileged(self) -> bool {
        self.guild_members() || self.guild_presences()
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILDS] intent.
    ///
    /// [GUILDS]: Self::GUILDS
    pub fn guilds(self) -> bool {
        self.contains(Self::GUILDS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_MESSAGES] intent.
    ///
    /// [GUILD_MESSAGES]: Self::GUILD_MESSAGES
    pub fn guild_messages(self) -> bool {
        self.contains(Self::GUILD_MESSAGES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_MEMBERS] intent.
    ///
    /// [GUILD_MEMBERS]: Self::GUILD_MEMBERS
    pub fn guild_members(self) -> bool {
        self.contains(Self::GUILD_MEMBERS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_BANS] intent.
    ///
    /// [GUILD_BANS]: Self::GUILD_BANS
    pub fn guild_bans(self) -> bool {
        self.contains(Self::GUILD_BANS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_EMOJIS] intent.
    ///
    /// [GUILD_EMOJIS]: Self::GUILD_EMOJIS
    pub fn guild_emojis(self) -> bool {
        self.contains(Self::GUILD_EMOJIS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_INTEGRATIONS] intent.
    ///
    /// [GUILD_INTEGRATIONS]: Self::GUILD_INTEGRATIONS
    pub fn guild_integrations(self) -> bool {
        self.contains(Self::GUILD_INTEGRATIONS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_WEBHOOKS] intent.
    ///
    /// [GUILD_WEBHOOKS]: Self::GUILD_WEBHOOKS
    pub fn guild_webhooks(self) -> bool {
        self.contains(Self::GUILD_WEBHOOKS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_INVITES] intent.
    ///
    /// [GUILD_INVITES]: Self::GUILD_INVITES
    pub fn guild_invites(self) -> bool {
        self.contains(Self::GUILD_INVITES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_VOICE_STATES] intent.
    ///
    /// [GUILD_VOICE_STATES]: Self::GUILD_VOICE_STATES
    pub fn guild_voice_states(self) -> bool {
        self.contains(Self::GUILD_VOICE_STATES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_PRESENCES] intent.
    ///
    /// [GUILD_PRESENCES]: Self::GUILD_PRESENCES
    pub fn guild_presences(self) -> bool {
        self.contains(Self::GUILD_PRESENCES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_MESSAGE_REACTIONS] intent.
    ///
    /// [GUILD_MESSAGE_REACTIONS]: Self::GUILD_MESSAGE_REACTIONS
    pub fn guild_message_reactions(self) -> bool {
        self.contains(Self::GUILD_MESSAGE_REACTIONS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [GUILD_MESSAGE_TYPING] intent.
    ///
    /// [GUILD_MESSAGE_TYPING]: Self::GUILD_MESSAGE_TYPING
    pub fn guild_message_typing(self) -> bool {
        self.contains(Self::GUILD_MESSAGE_TYPING)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [DIRECT_MESSAGES] intent.
    ///
    /// [DIRECT_MESSAGES]: Self::DIRECT_MESSAGES
    pub fn direct_messages(self) -> bool {
        self.contains(Self::DIRECT_MESSAGES)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [DIRECT_MESSAGE_REACTIONS] intent.
    ///
    /// [DIRECT_MESSAGE_REACTIONS]: Self::DIRECT_MESSAGE_REACTIONS
    pub fn direct_message_reactions(self) -> bool {
        self.contains(Self::DIRECT_MESSAGE_REACTIONS)
    }

    /// Shorthand for checking that the set of intents contains the
    /// [DIRECT_MESSAGE_TYPING] intent.
    ///
    /// [DIRECT_MESSAGE_TYPING]: Self::DIRECT_MESSAGE_TYPING
    pub fn direct_message_typing(self) -> bool {
        self.contains(Self::DIRECT_MESSAGE_TYPING)
    }
}
<|endoftext|>


<commit_before>use crate::command_prelude::*;

use cargo::core::{GitReference, SourceId};
use cargo::ops;
use cargo::util::IntoUrl;

pub fn cli() -> App {
    subcommand("install")
        .about("Install a Rust binary. Default location is $HOME/.cargo/bin")
        .arg(opt("quiet", "No output printed to stdout").short("q"))
        .arg(Arg::with_name("crate").empty_values(false).multiple(true))
        .arg(
            opt("version", "Specify a version to install")
                .alias("vers")
                .value_name("VERSION")
                .requires("crate"),
        )
        .arg(
            opt("git", "Git URL to install the specified crate from")
                .value_name("URL")
                .conflicts_with_all(&["path", "index", "registry"]),
        )
        .arg(
            opt("branch", "Branch to use when installing from git")
                .value_name("BRANCH")
                .requires("git"),
        )
        .arg(
            opt("tag", "Tag to use when installing from git")
                .value_name("TAG")
                .requires("git"),
        )
        .arg(
            opt("rev", "Specific commit to use when installing from git")
                .value_name("SHA")
                .requires("git"),
        )
        .arg(
            opt("path", "Filesystem path to local crate to install")
                .value_name("PATH")
                .conflicts_with_all(&["git", "index", "registry"]),
        )
        .arg(opt(
            "list",
            "list all installed packages and their versions",
        ))
        .arg_jobs()
        .arg(opt("force", "Force overwriting existing crates or binaries").short("f"))
        .arg(opt("no-track", "Do not save tracking information"))
        .arg_features()
        .arg_profile("Install artifacts with the specified profile")
        .arg(opt("debug", "Build in debug mode instead of release mode"))
        .arg_targets_bins_examples(
            "Install only the specified binary",
            "Install all binaries",
            "Install only the specified example",
            "Install all examples",
        )
        .arg_target_triple("Build for the target triple")
        .arg_target_dir()
        .arg(opt("root", "Directory to install packages into").value_name("DIR"))
        .arg(
            opt("index", "Registry index to install from")
                .value_name("INDEX")
                .requires("crate")
                .conflicts_with_all(&["git", "path", "registry"]),
        )
        .arg(
            opt("registry", "Registry to use")
                .value_name("REGISTRY")
                .requires("crate")
                .conflicts_with_all(&["git", "path", "index"]),
        )
        .after_help("Run `cargo help install` for more detailed information.\n")
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    if let Some(path) = args.value_of_path("path", config) {
        config.reload_rooted_at(path)?;
    } else {
        config.reload_rooted_at(config.home().clone().into_path_unlocked())?;
    }

    let workspace = args.workspace(config).ok();
    let mut compile_opts = args.compile_options(
        config,
        CompileMode::Build,
        workspace.as_ref(),
        ProfileChecking::Checked,
    )?;

    compile_opts.build_config.requested_profile =
        args.get_profile_name(config, "release", ProfileChecking::Checked)?;

    let krates = args
        .values_of("crate")
        .unwrap_or_default()
        .collect::<Vec<_>>();

    let mut from_cwd = false;

    let source = if let Some(url) = args.value_of("git") {
        let url = url.into_url()?;
        let gitref = if let Some(branch) = args.value_of("branch") {
            GitReference::Branch(branch.to_string())
        } else if let Some(tag) = args.value_of("tag") {
            GitReference::Tag(tag.to_string())
        } else if let Some(rev) = args.value_of("rev") {
            GitReference::Rev(rev.to_string())
        } else {
            GitReference::DefaultBranch
        };
        SourceId::for_git(&url, gitref)?
    } else if let Some(path) = args.value_of_path("path", config) {
        SourceId::for_path(&path)?
    } else if krates.is_empty() {
        from_cwd = true;
        SourceId::for_path(config.cwd())?
    } else if let Some(registry) = args.registry(config)? {
        SourceId::alt_registry(config, &registry)?
    } else if let Some(index) = args.value_of("index") {
        SourceId::for_registry(&index.into_url()?)?
    } else {
        SourceId::crates_io(config)?
    };

    let version = args.value_of("version");
    let root = args.value_of("root");

    if args.is_present("list") {
        ops::install_list(root, config)?;
    } else {
        ops::install(
            config,
            root,
            krates,
            source,
            from_cwd,
            version,
            &compile_opts,
            args.is_present("force"),
            args.is_present("no-track"),
        )?;
    }
    Ok(())
}
<commit_msg>Sweep unrelated message from unnecessary workspace infromation<commit_after>use crate::command_prelude::*;

use cargo::core::{GitReference, SourceId};
use cargo::ops;
use cargo::util::IntoUrl;

pub fn cli() -> App {
    subcommand("install")
        .about("Install a Rust binary. Default location is $HOME/.cargo/bin")
        .arg(opt("quiet", "No output printed to stdout").short("q"))
        .arg(Arg::with_name("crate").empty_values(false).multiple(true))
        .arg(
            opt("version", "Specify a version to install")
                .alias("vers")
                .value_name("VERSION")
                .requires("crate"),
        )
        .arg(
            opt("git", "Git URL to install the specified crate from")
                .value_name("URL")
                .conflicts_with_all(&["path", "index", "registry"]),
        )
        .arg(
            opt("branch", "Branch to use when installing from git")
                .value_name("BRANCH")
                .requires("git"),
        )
        .arg(
            opt("tag", "Tag to use when installing from git")
                .value_name("TAG")
                .requires("git"),
        )
        .arg(
            opt("rev", "Specific commit to use when installing from git")
                .value_name("SHA")
                .requires("git"),
        )
        .arg(
            opt("path", "Filesystem path to local crate to install")
                .value_name("PATH")
                .conflicts_with_all(&["git", "index", "registry"]),
        )
        .arg(opt(
            "list",
            "list all installed packages and their versions",
        ))
        .arg_jobs()
        .arg(opt("force", "Force overwriting existing crates or binaries").short("f"))
        .arg(opt("no-track", "Do not save tracking information"))
        .arg_features()
        .arg_profile("Install artifacts with the specified profile")
        .arg(opt("debug", "Build in debug mode instead of release mode"))
        .arg_targets_bins_examples(
            "Install only the specified binary",
            "Install all binaries",
            "Install only the specified example",
            "Install all examples",
        )
        .arg_target_triple("Build for the target triple")
        .arg_target_dir()
        .arg(opt("root", "Directory to install packages into").value_name("DIR"))
        .arg(
            opt("index", "Registry index to install from")
                .value_name("INDEX")
                .requires("crate")
                .conflicts_with_all(&["git", "path", "registry"]),
        )
        .arg(
            opt("registry", "Registry to use")
                .value_name("REGISTRY")
                .requires("crate")
                .conflicts_with_all(&["git", "path", "index"]),
        )
        .after_help("Run `cargo help install` for more detailed information.\n")
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    let workspace;
    if let Some(path) = args.value_of_path("path", config) {
        config.reload_rooted_at(path)?;
        // Only provide worksapce information for local crate installation
        workspace = args.workspace(config).ok();
    } else {
        config.reload_rooted_at(config.home().clone().into_path_unlocked())?;
        workspace = None;
    }

    let mut compile_opts = args.compile_options(
        config,
        CompileMode::Build,
        workspace.as_ref(),
        ProfileChecking::Checked,
    )?;

    compile_opts.build_config.requested_profile =
        args.get_profile_name(config, "release", ProfileChecking::Checked)?;

    let krates = args
        .values_of("crate")
        .unwrap_or_default()
        .collect::<Vec<_>>();

    let mut from_cwd = false;

    let source = if let Some(url) = args.value_of("git") {
        let url = url.into_url()?;
        let gitref = if let Some(branch) = args.value_of("branch") {
            GitReference::Branch(branch.to_string())
        } else if let Some(tag) = args.value_of("tag") {
            GitReference::Tag(tag.to_string())
        } else if let Some(rev) = args.value_of("rev") {
            GitReference::Rev(rev.to_string())
        } else {
            GitReference::DefaultBranch
        };
        SourceId::for_git(&url, gitref)?
    } else if let Some(path) = args.value_of_path("path", config) {
        SourceId::for_path(&path)?
    } else if krates.is_empty() {
        from_cwd = true;
        SourceId::for_path(config.cwd())?
    } else if let Some(registry) = args.registry(config)? {
        SourceId::alt_registry(config, &registry)?
    } else if let Some(index) = args.value_of("index") {
        SourceId::for_registry(&index.into_url()?)?
    } else {
        SourceId::crates_io(config)?
    };

    let version = args.value_of("version");
    let root = args.value_of("root");

    if args.is_present("list") {
        ops::install_list(root, config)?;
    } else {
        ops::install(
            config,
            root,
            krates,
            source,
            from_cwd,
            version,
            &compile_opts,
            args.is_present("force"),
            args.is_present("no-track"),
        )?;
    }
    Ok(())
}
<|endoftext|>


<commit_before>// Copyright 2016 The Grin Developers
//
// 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.

//! Implements storage primitives required by the chain

use secp::pedersen::Commitment;

use types::*;
use core::core::hash::{Hash, Hashed};
use core::core::{Block, BlockHeader, Output};
use grin_store::{self, Error, to_key, u64_to_key, option_to_not_found};

const STORE_SUBPATH: &'static str = "chain";

const BLOCK_HEADER_PREFIX: u8 = 'h' as u8;
const BLOCK_PREFIX: u8 = 'b' as u8;
const HEAD_PREFIX: u8 = 'H' as u8;
const HEADER_HEAD_PREFIX: u8 = 'I' as u8;
const HEADER_HEIGHT_PREFIX: u8 = '8' as u8;
const OUTPUT_COMMIT_PREFIX: u8 = 'o' as u8;

/// An implementation of the ChainStore trait backed by a simple key-value
/// store.
pub struct ChainKVStore {
	db: grin_store::Store,
}

impl ChainKVStore {
	pub fn new(root_path: String) -> Result<ChainKVStore, Error> {
		let db = grin_store::Store::open(format!("{}/{}", root_path, STORE_SUBPATH).as_str())?;
		Ok(ChainKVStore { db: db })
	}
}

impl ChainStore for ChainKVStore {
	fn head(&self) -> Result<Tip, Error> {
		option_to_not_found(self.db.get_ser(&vec![HEAD_PREFIX]))
	}

	fn head_header(&self) -> Result<BlockHeader, Error> {
		let head: Tip = try!(option_to_not_found(self.db.get_ser(&vec![HEAD_PREFIX])));
		self.get_block_header(&head.last_block_h)
	}

	fn save_head(&self, t: &Tip) -> Result<(), Error> {
		self.db
			.batch()
			.put_ser(&vec![HEAD_PREFIX], t)?
			.put_ser(&vec![HEADER_HEAD_PREFIX], t)?
			.write()
	}

	fn save_body_head(&self, t: &Tip) -> Result<(), Error> {
		self.db.put_ser(&vec![HEAD_PREFIX], t)
	}

	fn get_header_head(&self) -> Result<Tip, Error> {
		option_to_not_found(self.db.get_ser(&vec![HEADER_HEAD_PREFIX]))
	}

	fn save_header_head(&self, t: &Tip) -> Result<(), Error> {
		self.db.put_ser(&vec![HEADER_HEAD_PREFIX], t)
	}

	fn get_block(&self, h: &Hash) -> Result<Block, Error> {
		option_to_not_found(self.db.get_ser(&to_key(BLOCK_PREFIX, &mut h.to_vec())))
	}

	fn get_block_header(&self, h: &Hash) -> Result<BlockHeader, Error> {
		option_to_not_found(self.db.get_ser(&to_key(BLOCK_HEADER_PREFIX, &mut h.to_vec())))
	}

	fn check_block_exists(&self, h: &Hash) -> Result<bool, Error> {
		self.db.exists(&to_key(BLOCK_PREFIX, &mut h.to_vec()))
	}

	fn save_block(&self, b: &Block) -> Result<(), Error> {
		// saving the block and its header
		let mut batch = self.db
			.batch()
			.put_ser(&to_key(BLOCK_PREFIX, &mut b.hash().to_vec())[..], b)?
			.put_ser(&to_key(BLOCK_HEADER_PREFIX, &mut b.hash().to_vec())[..],
			         &b.header)?;

		// saving the full output under its hash, as well as a commitment to hash index
		for out in &b.outputs {
			let mut out_bytes = out.commit.as_ref().to_vec();
			println!("OUTSAVE: {:?}", out_bytes);
			batch = batch.put_enc(&mut BlockCodec::default(),
				         &to_key(OUTPUT_COMMIT_PREFIX, &mut out_bytes)[..],
				         out.hash().clone())?;
		}
		batch.write()
	}

	fn save_block_header(&self, bh: &BlockHeader) -> Result<(), Error> {
		self.db.put_ser(&to_key(BLOCK_HEADER_PREFIX, &mut bh.hash().to_vec())[..],
		                bh)
	}

	fn get_header_by_height(&self, height: u64) -> Result<BlockHeader, Error> {
		option_to_not_found(self.db.get_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, height)))
	}

	fn get_output_by_commit(&self, commit: &Commitment) -> Result<Output, Error> {
		option_to_not_found(self.db.get_dec(&mut BlockCodec::default(),
		                                    &to_key(OUTPUT_COMMIT_PREFIX,
		                                            &mut commit.as_ref().to_vec())))
	}

	fn has_output_commit(&self, commit: &Commitment) -> Result<Hash, Error> {
		option_to_not_found(self.db
			.get_ser(&to_key(OUTPUT_COMMIT_PREFIX, &mut commit.as_ref().to_vec())))
	}

	fn setup_height(&self, bh: &BlockHeader) -> Result<(), Error> {
		self.db.put_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, bh.height), bh)?;

		let mut prev_h = bh.previous;
		let mut prev_height = bh.height - 1;
		while prev_height > 0 {
			let prev = self.get_header_by_height(prev_height)?;
			if prev.hash() != prev_h {
				let real_prev = self.get_block_header(&prev_h)?;
				self.db
					.put_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, real_prev.height),
					         &real_prev);
				prev_h = real_prev.previous;
				prev_height = real_prev.height - 1;
			} else {
				break;
			}
		}
		Ok(())
	}
}
<commit_msg>Fix partial revert<commit_after>// Copyright 2016 The Grin Developers
//
// 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.

//! Implements storage primitives required by the chain

use secp::pedersen::Commitment;

use types::*;
use core::core::hash::{Hash, Hashed};
use core::core::{Block, BlockHeader, Output};
use grin_store::{self, Error, to_key, u64_to_key, option_to_not_found};

const STORE_SUBPATH: &'static str = "chain";

const BLOCK_HEADER_PREFIX: u8 = 'h' as u8;
const BLOCK_PREFIX: u8 = 'b' as u8;
const HEAD_PREFIX: u8 = 'H' as u8;
const HEADER_HEAD_PREFIX: u8 = 'I' as u8;
const HEADER_HEIGHT_PREFIX: u8 = '8' as u8;
const OUTPUT_COMMIT_PREFIX: u8 = 'o' as u8;

/// An implementation of the ChainStore trait backed by a simple key-value
/// store.
pub struct ChainKVStore {
	db: grin_store::Store,
}

impl ChainKVStore {
	pub fn new(root_path: String) -> Result<ChainKVStore, Error> {
		let db = grin_store::Store::open(format!("{}/{}", root_path, STORE_SUBPATH).as_str())?;
		Ok(ChainKVStore { db: db })
	}
}

impl ChainStore for ChainKVStore {
	fn head(&self) -> Result<Tip, Error> {
		option_to_not_found(self.db.get_ser(&vec![HEAD_PREFIX]))
	}

	fn head_header(&self) -> Result<BlockHeader, Error> {
		let head: Tip = try!(option_to_not_found(self.db.get_ser(&vec![HEAD_PREFIX])));
		self.get_block_header(&head.last_block_h)
	}

	fn save_head(&self, t: &Tip) -> Result<(), Error> {
		self.db
			.batch()
			.put_ser(&vec![HEAD_PREFIX], t)?
			.put_ser(&vec![HEADER_HEAD_PREFIX], t)?
			.write()
	}

	fn save_body_head(&self, t: &Tip) -> Result<(), Error> {
		self.db.put_ser(&vec![HEAD_PREFIX], t)
	}

	fn get_header_head(&self) -> Result<Tip, Error> {
		option_to_not_found(self.db.get_ser(&vec![HEADER_HEAD_PREFIX]))
	}

	fn save_header_head(&self, t: &Tip) -> Result<(), Error> {
		self.db.put_ser(&vec![HEADER_HEAD_PREFIX], t)
	}

	fn get_block(&self, h: &Hash) -> Result<Block, Error> {
		option_to_not_found(self.db.get_ser(&to_key(BLOCK_PREFIX, &mut h.to_vec())))
	}

	fn get_block_header(&self, h: &Hash) -> Result<BlockHeader, Error> {
		option_to_not_found(self.db.get_ser(&to_key(BLOCK_HEADER_PREFIX, &mut h.to_vec())))
	}

	fn check_block_exists(&self, h: &Hash) -> Result<bool, Error> {
		self.db.exists(&to_key(BLOCK_PREFIX, &mut h.to_vec()))
	}

	fn save_block(&self, b: &Block) -> Result<(), Error> {
		// saving the block and its header
		let mut batch = self.db
			.batch()
			.put_ser(&to_key(BLOCK_PREFIX, &mut b.hash().to_vec())[..], b)?
			.put_ser(&to_key(BLOCK_HEADER_PREFIX, &mut b.hash().to_vec())[..],
			         &b.header)?;

		// saving the full output under its hash, as well as a commitment to hash index
		for out in &b.outputs {
			let mut out_bytes = out.commit.as_ref().to_vec();
			println!("OUTSAVE: {:?}", out_bytes);
			batch = batch.put_ser(&to_key(OUTPUT_COMMIT_PREFIX, &mut out_bytes)[..],
				         &out.hash())?;
		}
		batch.write()
	}

	fn save_block_header(&self, bh: &BlockHeader) -> Result<(), Error> {
		self.db.put_ser(&to_key(BLOCK_HEADER_PREFIX, &mut bh.hash().to_vec())[..],
		                bh)
	}

	fn get_header_by_height(&self, height: u64) -> Result<BlockHeader, Error> {
		option_to_not_found(self.db.get_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, height)))
	}

	fn get_output_by_commit(&self, commit: &Commitment) -> Result<Output, Error> {
		option_to_not_found(self.db.get_ser(&to_key(OUTPUT_COMMIT_PREFIX,
		                                            &mut commit.as_ref().to_vec())))
	}

	fn has_output_commit(&self, commit: &Commitment) -> Result<Hash, Error> {
		option_to_not_found(self.db
			.get_ser(&to_key(OUTPUT_COMMIT_PREFIX, &mut commit.as_ref().to_vec())))
	}

	fn setup_height(&self, bh: &BlockHeader) -> Result<(), Error> {
		self.db.put_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, bh.height), bh)?;

		let mut prev_h = bh.previous;
		let mut prev_height = bh.height - 1;
		while prev_height > 0 {
			let prev = self.get_header_by_height(prev_height)?;
			if prev.hash() != prev_h {
				let real_prev = self.get_block_header(&prev_h)?;
				self.db
					.put_ser(&u64_to_key(HEADER_HEIGHT_PREFIX, real_prev.height),
					         &real_prev);
				prev_h = real_prev.previous;
				prev_height = real_prev.height - 1;
			} else {
				break;
			}
		}
		Ok(())
	}
}
<|endoftext|>


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

use std::raw::Repr;

pub mod ll;
pub mod ops;

pub trait Vector<T> {
    fn inc(&self) -> i32;
    fn len(&self) -> i32;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

impl<T> Vector<T> for Vec<T> {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.len());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.as_slice().as_ptr() }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.as_mut_slice().as_mut_ptr() }
}

impl<'a, T> Vector<T> for &'a [T] {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.len());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.repr().data }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.repr().data as *mut T }
}
<commit_msg>Add VectorOperations trait<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use std::raw::Repr;
use vector::ops::{Copy, Axpy, Scal, Dot, Nrm2, Asum, Iamax};

pub mod ll;
pub mod ops;

pub trait Vector<T> {
    fn inc(&self) -> i32;
    fn len(&self) -> i32;
    fn as_ptr(&self) -> *const T;
    fn as_mut_ptr(&mut self) -> *mut T;
}

pub trait VectorOperations<T>: Vector<T>
    where T: Copy + Axpy + Scal + Dot + Nrm2 + Asum + Iamax {

    #[inline]
    fn into_vec(&self) -> Vec<T> {
        let n = self.len() as uint;

        let mut x = Vec::with_capacity(n);
        Copy::copy(self, &mut x);
        unsafe { x.set_len(n); }

        x
    }

    #[inline]
    fn update(&mut self, alpha: &T, x: &Vector<T>) -> &mut Self {
        Axpy::axpy(alpha, x, self);
        self
    }

    #[inline]
    fn scale(&mut self, alpha: &T) -> &mut Self {
        Scal::scal(alpha, self);
        self
    }

    #[inline]
    fn dot(&self, x: &Vector<T>) -> T {
        Dot::dot(self, x)
    }

    #[inline]
    fn abs_sum(&self) -> T {
        Asum::asum(self)
    }

    #[inline]
    fn norm(&self) -> T {
        Nrm2::nrm2(self)
    }

    #[inline]
    fn max_index(&self) -> uint {
        Iamax::iamax(self)
    }
}

impl<T> Vector<T> for Vec<T> {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.len());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.as_slice().as_ptr() }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.as_mut_slice().as_mut_ptr() }
}

impl<'a, T> Vector<T> for &'a [T] {
    #[inline]
    fn inc(&self) -> i32 { 1i32 }

    #[inline]
    fn len(&self) -> i32 {
        let l: Option<i32> = NumCast::from(self.len());
        match l {
            Some(l) => l,
            None => panic!(),
        }
    }

    #[inline]
    fn as_ptr(&self) -> *const T { self.repr().data }

    #[inline]
    fn as_mut_ptr(&mut self) -> *mut T { self.repr().data as *mut T }
}
<|endoftext|>


<commit_before>use core::ptr::Unique;
use core::fmt;
use spin::Mutex;

const BUFFER_HEIGHT: usize = 25;
const BUFFER_WIDTH: usize = 80;

pub static WRITER: Mutex<Writer> = Mutex::new(Writer {
    column_position: 0,
    color_code: ColorCode::new(Color::LightGreen, Color::Black),
    buffer: unsafe{Unique::new(0xb8000 as *mut _)},
});

macro_rules! println {
    ($fmt:expr) => (print!(concat!($fmt, "\n")));
    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}

macro_rules! print {
    ($($arg:tt)*) => ({
            use core::fmt::Write;
            $crate::vga_buffer::WRITER.lock().write_fmt(format_args!($($arg)*)).unwrap();
    });
}

pub fn clear_screen() {
    for _ in 0..BUFFER_HEIGHT {
        println!("");
    }
}

#[allow(dead_code)]
#[repr(u8)]
pub enum Color {
    Black      = 0,
    Blue       = 1,
    Green      = 2,
    Cyan       = 3,
    Red        = 4,
    Magenta    = 5,
    Brown      = 6,
    LightGray  = 7,
    DarkGray   = 8,
    LightBlue  = 9,
    LightGreen = 10,
    LightCyan  = 11,
    LightRed   = 12,
    Pink       = 13,
    Yellow     = 14,
    White      = 15,
}

pub struct Writer {
    column_position: usize,
    color_code: ColorCode,
    buffer: Unique<Buffer>,
}

impl Writer {
    pub fn write_byte(&mut self, byte: u8) {
        match byte {
            b'\n' => self.new_line(),
            byte => {
                if self.column_position >= BUFFER_WIDTH {
                    self.new_line();
                }
                let row = BUFFER_HEIGHT - 1;
                let col = self.column_position;

                self.buffer().chars[row][col] = ScreenChar {
                    ascii_character: byte,
                    color_code: self.color_code,
                };
                self.column_position += 1;
            }
        }
    }

    fn buffer(&mut self) -> &mut Buffer {
        unsafe{self.buffer.get_mut()}
    }

    fn new_line(&mut self) {
        for row in 0..(BUFFER_HEIGHT-1) {
            let buffer = self.buffer();
            buffer.chars[row] = buffer.chars[row + 1]
        }
        self.clear_row(BUFFER_HEIGHT-1);
        self.column_position = 0;
    }

    fn clear_row(&mut self, row: usize) {
        let blank = ScreenChar {
            ascii_character: ' ' as u8,
            color_code: self.color_code,
        };
        self.buffer().chars[row] = [blank; BUFFER_WIDTH];
    }
}

impl fmt::Write for Writer {
    fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
        for byte in s.bytes() {
          self.write_byte(byte)
        }
        Ok(())
    }
}

#[derive(Clone, Copy)]
struct ColorCode(u8);

impl ColorCode {
    const fn new(foreground: Color, background: Color) -> ColorCode {
        ColorCode((background as u8) << 4 | (foreground as u8))
    }
}

#[derive(Clone, Copy)]
#[repr(C)]
struct ScreenChar {
    ascii_character: u8,
    color_code: ColorCode,
}

struct Buffer {
    chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
<commit_msg>Use a byte char instead of casting<commit_after>use core::ptr::Unique;
use core::fmt;
use spin::Mutex;

const BUFFER_HEIGHT: usize = 25;
const BUFFER_WIDTH: usize = 80;

pub static WRITER: Mutex<Writer> = Mutex::new(Writer {
    column_position: 0,
    color_code: ColorCode::new(Color::LightGreen, Color::Black),
    buffer: unsafe{Unique::new(0xb8000 as *mut _)},
});

macro_rules! println {
    ($fmt:expr) => (print!(concat!($fmt, "\n")));
    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
}

macro_rules! print {
    ($($arg:tt)*) => ({
            use core::fmt::Write;
            $crate::vga_buffer::WRITER.lock().write_fmt(format_args!($($arg)*)).unwrap();
    });
}

pub fn clear_screen() {
    for _ in 0..BUFFER_HEIGHT {
        println!("");
    }
}

#[allow(dead_code)]
#[repr(u8)]
pub enum Color {
    Black      = 0,
    Blue       = 1,
    Green      = 2,
    Cyan       = 3,
    Red        = 4,
    Magenta    = 5,
    Brown      = 6,
    LightGray  = 7,
    DarkGray   = 8,
    LightBlue  = 9,
    LightGreen = 10,
    LightCyan  = 11,
    LightRed   = 12,
    Pink       = 13,
    Yellow     = 14,
    White      = 15,
}

pub struct Writer {
    column_position: usize,
    color_code: ColorCode,
    buffer: Unique<Buffer>,
}

impl Writer {
    pub fn write_byte(&mut self, byte: u8) {
        match byte {
            b'\n' => self.new_line(),
            byte => {
                if self.column_position >= BUFFER_WIDTH {
                    self.new_line();
                }
                let row = BUFFER_HEIGHT - 1;
                let col = self.column_position;

                self.buffer().chars[row][col] = ScreenChar {
                    ascii_character: byte,
                    color_code: self.color_code,
                };
                self.column_position += 1;
            }
        }
    }

    fn buffer(&mut self) -> &mut Buffer {
        unsafe{self.buffer.get_mut()}
    }

    fn new_line(&mut self) {
        for row in 0..(BUFFER_HEIGHT-1) {
            let buffer = self.buffer();
            buffer.chars[row] = buffer.chars[row + 1]
        }
        self.clear_row(BUFFER_HEIGHT-1);
        self.column_position = 0;
    }

    fn clear_row(&mut self, row: usize) {
        let blank = ScreenChar {
            ascii_character: b' ',
            color_code: self.color_code,
        };
        self.buffer().chars[row] = [blank; BUFFER_WIDTH];
    }
}

impl fmt::Write for Writer {
    fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
        for byte in s.bytes() {
          self.write_byte(byte)
        }
        Ok(())
    }
}

#[derive(Clone, Copy)]
struct ColorCode(u8);

impl ColorCode {
    const fn new(foreground: Color, background: Color) -> ColorCode {
        ColorCode((background as u8) << 4 | (foreground as u8))
    }
}

#[derive(Clone, Copy)]
#[repr(C)]
struct ScreenChar {
    ascii_character: u8,
    color_code: ColorCode,
}

struct Buffer {
    chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
}
<|endoftext|>


<commit_before>use term::*;
use term::Term::*;
use term::Error::*;
use booleans::*;

// 0 := λfx.x
pub fn zero() -> Term { abs(abs(Var(1))) }

// ISZERO := λn.n (λx.FALSE) TRUE
pub fn is_zero() -> Term { abs(Var(1).app(abs(fls())).app(tru())) }

// 1 := λfx.f x
pub fn one() -> Term { abs(abs(Var(2).app(Var(1)))) }

// SUCC := λnfx.f (n f x)
pub fn succ() -> Term { abs(abs(abs(Var(2).app(Var(3).app(Var(2)).app(Var(1)))))) }

// PLUS := λmnfx.m f (n f x)
pub fn plus() -> Term { abs(abs(abs(abs(Var(4).app(Var(2)).app(Var(3).app(Var(2)).app(Var(1))))))) }

// PLUS := λmn.m SUCC n
// pub fn plus2() -> Term { abs(abs(Var(2).app(succ()).app(Var(1)))) }

// MULT := λmnf.m (n f)
pub fn mult() -> Term { abs(abs(abs(Var(3).app(Var(2).app(Var(1)))))) }

// MULT := λmn.m (PLUS n) 0
// pub fn mult2() -> Term { abs(abs(Var(2).app(plus().app(Var(1))).app(zero()))) }

// POW := λbe.e b
pub fn pow() -> Term { abs(abs(Var(1).app(Var(2)))) }

// PRED := λnfx.n (λgh.h (g f)) (λu.x) (λu.u)
pub fn pred() -> Term { abs(abs(abs(Var(3).app(abs(abs(Var(1).app(Var(2).app(Var(4)))))).app(abs(Var(2))).app(abs(Var(1)))))) }

// PRED := λn.n (λgk.ISZERO (g 1) k (PLUS (g k) 1)) (λv.0) 0
// pub fn pred2() -> Term { abs(Var(1).app(abs(abs(is_zero().app(Var(2).app(one())).app(Var(1)).app(plus().app(Var(2).app(Var(1))).app(one()))))).app(abs(zero())).app(zero())) }

// SUB := λmn.n PRED m
pub fn sub() -> Term { abs(abs(Var(1).app(pred()).app(Var(2)))) }

// LEQ := λmn.ISZERO (SUB m n)
pub fn leq() -> Term { abs(abs(is_zero().app(sub().app(Var(2)).app(Var(1))))) }

// EQ := λmn.AND (LEQ m n) (LEQ n m)
pub fn eq() -> Term { abs(abs(and().app(leq().app(Var(2)).app(Var(1))).app(leq().app(Var(1)).app(Var(2))))) }

impl Term {
	pub fn value(&self) -> Result<usize, Error> {
		if let Ok(ref inner) = self.unabs_ref().and_then(|t| t.unabs_ref()) {
			Ok(try!(inner._value()))
		} else {
			Err(NotANum)
		}
	}

	fn _value(&self) -> Result<usize, Error> {
		if let Ok(ref rhs) = self.rhs_ref() {
			Ok(1 + try!(rhs._value()))
		} else if let Var(n) = *self {
			if n == 1 {
				Ok(0)
			} else {
				Err(NotANum)
			}
		} else {
			Err(NotANum)
		}
	}

	pub fn is_number(&self) -> bool { self.value().is_ok() }
}

pub fn to_cnum(n: usize) -> Term {
	let mut inner = Var(1);
	let mut count = n;

	while count > 0 {
		inner = Var(2).app(inner);
		count -= 1;
	}

	abs(abs(inner))
}

#[cfg(test)]
mod test {
	use super::*;
	use reduction::*;

	#[test]
	fn church_zero() {
		assert_eq!(normalize(is_zero().app(zero())), tru())
	}

	#[test]
	fn church_successor() {
		assert_eq!(normalize(succ().app(zero())), one());
		assert_eq!(normalize(succ().app(one())), abs(abs(Var(2).app(Var(2).app(Var(1))))));
		assert_eq!(normalize(succ().app(succ().app(succ().app(zero())))), abs(abs(Var(2).app(Var(2).app(Var(2).app(Var(1)))))));
	}

	#[test]
	fn church_number_identification() {
		for n in 0..5 { assert!(to_cnum(n).is_number()) }
	}

	#[test]
	fn church_number_creation() {
		assert_eq!(to_cnum(0), zero());
		assert_eq!(to_cnum(1), one());
		assert_eq!(to_cnum(2), normalize(succ().app(one())));
	}

	#[test]
	fn church_number_values() {
		for n in 0..10 { assert_eq!(to_cnum(n).value(), Ok(n)) }

		assert_eq!(abs(Var(1)).value(),      Err(NotANum));
		assert_eq!(abs(abs(Var(2))).value(), Err(NotANum));
	}

	#[test]
	fn church_addition() {
		assert_eq!(normalize(plus().app(one())), succ()); // PLUS 1 → SUCC

		assert_eq!(normalize(plus().app(zero()).app(zero())), zero());
		assert_eq!(normalize(plus().app(zero()).app(one())),  one());
		assert_eq!(normalize(plus().app(one()).app(zero())),  one());
		assert_eq!(normalize(plus().app(one()).app(one())),   to_cnum(2));

		assert_eq!(normalize(plus().app(to_cnum(2)).app(to_cnum(3))), to_cnum(5));
		assert_eq!(normalize(plus().app(to_cnum(4)).app(to_cnum(4))), to_cnum(8));
	}

	#[test]
	fn church_multiplication() {
		assert_eq!(normalize(mult().app(to_cnum(3)).app(to_cnum(4))), to_cnum(12));
		assert_eq!(normalize(mult().app(to_cnum(1)).app(to_cnum(3))), to_cnum(3));
		assert_eq!(normalize(mult().app(to_cnum(5)).app(to_cnum(0))), to_cnum(0));
	}

	#[test]
	fn church_exponentiation() {
		assert_eq!(normalize(pow().app(to_cnum(2)).app(to_cnum(4))), to_cnum(16));
		assert_eq!(normalize(pow().app(to_cnum(1)).app(to_cnum(6))), to_cnum(1));
		assert_eq!(normalize(pow().app(to_cnum(3)).app(to_cnum(2))), to_cnum(9));
//		assert_eq!(normalize(pow().app(to_cnum(5)).app(zero())), to_cnum(1)); // n^0 fails - why?
	}

	#[test]
	fn church_predecessor() {
		assert_eq!(normalize(pred().app(zero())), zero());
		assert_eq!(normalize(pred().app(one())), zero());
		assert_eq!(normalize(pred().app(to_cnum(5))), to_cnum(4));
	}

	#[test]
	fn church_comparison() {
		assert_eq!(normalize(leq().app(zero()).app(zero())), tru());
		assert_eq!(normalize(leq().app(zero()).app(one())), tru());

		assert_eq!(normalize(eq().app(zero()).app(zero())), tru());
		assert_eq!(normalize(eq().app(zero()).app(one())), fls());
		assert_eq!(normalize(eq().app(one()).app(zero())), fls());
		// TODO: add lt, gt, geq
	}
}<commit_msg>Delete arithmetic.rs<commit_after><|endoftext|>


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

use dom::bindings::codegen::BindingDeclarations::UIEventBinding;
use dom::bindings::codegen::InheritTypes::{EventCast, UIEventDerived};
use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, OptionalSettable};
use dom::bindings::error::Fallible;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, EventMethods, EventTypeId, UIEventTypeId};
use dom::node::Node;
use dom::window::Window;
use servo_util::str::DOMString;

use serialize::{Encoder, Encodable};

#[deriving(Encodable)]
pub struct UIEvent {
    pub event: Event,
    pub view: Option<JS<Window>>,
    pub detail: i32
}

impl UIEventDerived for Event {
    fn is_uievent(&self) -> bool {
        self.type_id == UIEventTypeId
    }
}

impl UIEvent {
    pub fn new_inherited(type_id: EventTypeId) -> UIEvent {
        UIEvent {
            event: Event::new_inherited(type_id),
            view: None,
            detail: 0
        }
    }

    pub fn new_uninitialized(window: &JSRef<Window>) -> Temporary<UIEvent> {
        reflect_dom_object(box UIEvent::new_inherited(UIEventTypeId),
                           window,
                           UIEventBinding::Wrap)
    }

    pub fn new(window: &JSRef<Window>,
               type_: DOMString,
               can_bubble: bool,
               cancelable: bool,
               view: Option<JSRef<Window>>,
               detail: i32) -> Temporary<UIEvent> {
        let mut ev = UIEvent::new_uninitialized(window).root();
        ev.InitUIEvent(type_, can_bubble, cancelable, view, detail);
        Temporary::from_rooted(&*ev)
    }

    pub fn Constructor(owner: &JSRef<Window>,
                       type_: DOMString,
                       init: &UIEventBinding::UIEventInit) -> Fallible<Temporary<UIEvent>> {
        let event = UIEvent::new(owner, type_,
                                 init.parent.bubbles, init.parent.cancelable,
                                 init.view.root_ref(), init.detail);
        Ok(event)
    }
}

pub trait UIEventMethods {
    fn GetView(&self) -> Option<Temporary<Window>>;
    fn Detail(&self) -> i32;
    fn LayerX(&self) -> i32;
    fn LayerY(&self) -> i32;
    fn PageX(&self) -> i32;
    fn PageY(&self) -> i32;
    fn Which(&self) -> u32;
    fn GetRangeParent(&self) -> Option<Temporary<Node>>;
    fn RangeOffset(&self) -> i32;
    fn CancelBubble(&self) -> bool;
    fn SetCancelBubble(&mut self, _val: bool);
    fn IsChar(&self) -> bool;
    fn InitUIEvent(&mut self,
                   type_: DOMString,
                   can_bubble: bool,
                   cancelable: bool,
                   view: Option<JSRef<Window>>,
                   detail: i32);
}

impl<'a> UIEventMethods for JSRef<'a, UIEvent> {
    fn GetView(&self) -> Option<Temporary<Window>> {
        self.view.map(|view| Temporary::new(view))
    }

    fn Detail(&self) -> i32 {
        self.detail
    }

    fn InitUIEvent(&mut self,
                   type_: DOMString,
                   can_bubble: bool,
                   cancelable: bool,
                   view: Option<JSRef<Window>>,
                   detail: i32) {
        {
            let event: &mut JSRef<Event> = EventCast::from_mut_ref(self);
            event.InitEvent(type_, can_bubble, cancelable);
        }
        self.view.assign(view);
        self.detail = detail;
    }

    fn LayerX(&self) -> i32 {
        //TODO
        0
    }

    fn LayerY(&self) -> i32 {
        //TODO
        0
    }

    fn PageX(&self) -> i32 {
        //TODO
        0
    }

    fn PageY(&self) -> i32 {
        //TODO
        0
    }

    fn Which(&self) -> u32 {
        //TODO
        0
    }

    fn GetRangeParent(&self) -> Option<Temporary<Node>> {
        //TODO
        None
    }

    fn RangeOffset(&self) -> i32 {
        //TODO
        0
    }

    fn CancelBubble(&self) -> bool {
        //TODO
        false
    }

    fn SetCancelBubble(&mut self, _val: bool) {
        //TODO
    }

    fn IsChar(&self) -> bool {
        //TODO
        false
    }
}

impl Reflectable for UIEvent {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.event.reflector()
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        self.event.mut_reflector()
    }
}
<commit_msg>Remove needless '&mut self' from UIEventMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::UIEventBinding;
use dom::bindings::codegen::InheritTypes::{EventCast, UIEventDerived};
use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, OptionalSettable};
use dom::bindings::error::Fallible;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, EventMethods, EventTypeId, UIEventTypeId};
use dom::node::Node;
use dom::window::Window;
use servo_util::str::DOMString;

use serialize::{Encoder, Encodable};

#[deriving(Encodable)]
pub struct UIEvent {
    pub event: Event,
    pub view: Option<JS<Window>>,
    pub detail: i32
}

impl UIEventDerived for Event {
    fn is_uievent(&self) -> bool {
        self.type_id == UIEventTypeId
    }
}

impl UIEvent {
    pub fn new_inherited(type_id: EventTypeId) -> UIEvent {
        UIEvent {
            event: Event::new_inherited(type_id),
            view: None,
            detail: 0
        }
    }

    pub fn new_uninitialized(window: &JSRef<Window>) -> Temporary<UIEvent> {
        reflect_dom_object(box UIEvent::new_inherited(UIEventTypeId),
                           window,
                           UIEventBinding::Wrap)
    }

    pub fn new(window: &JSRef<Window>,
               type_: DOMString,
               can_bubble: bool,
               cancelable: bool,
               view: Option<JSRef<Window>>,
               detail: i32) -> Temporary<UIEvent> {
        let mut ev = UIEvent::new_uninitialized(window).root();
        ev.InitUIEvent(type_, can_bubble, cancelable, view, detail);
        Temporary::from_rooted(&*ev)
    }

    pub fn Constructor(owner: &JSRef<Window>,
                       type_: DOMString,
                       init: &UIEventBinding::UIEventInit) -> Fallible<Temporary<UIEvent>> {
        let event = UIEvent::new(owner, type_,
                                 init.parent.bubbles, init.parent.cancelable,
                                 init.view.root_ref(), init.detail);
        Ok(event)
    }
}

pub trait UIEventMethods {
    fn GetView(&self) -> Option<Temporary<Window>>;
    fn Detail(&self) -> i32;
    fn LayerX(&self) -> i32;
    fn LayerY(&self) -> i32;
    fn PageX(&self) -> i32;
    fn PageY(&self) -> i32;
    fn Which(&self) -> u32;
    fn GetRangeParent(&self) -> Option<Temporary<Node>>;
    fn RangeOffset(&self) -> i32;
    fn CancelBubble(&self) -> bool;
    fn SetCancelBubble(&self, _val: bool);
    fn IsChar(&self) -> bool;
    fn InitUIEvent(&mut self,
                   type_: DOMString,
                   can_bubble: bool,
                   cancelable: bool,
                   view: Option<JSRef<Window>>,
                   detail: i32);
}

impl<'a> UIEventMethods for JSRef<'a, UIEvent> {
    fn GetView(&self) -> Option<Temporary<Window>> {
        self.view.map(|view| Temporary::new(view))
    }

    fn Detail(&self) -> i32 {
        self.detail
    }

    fn InitUIEvent(&mut self,
                   type_: DOMString,
                   can_bubble: bool,
                   cancelable: bool,
                   view: Option<JSRef<Window>>,
                   detail: i32) {
        {
            let event: &mut JSRef<Event> = EventCast::from_mut_ref(self);
            event.InitEvent(type_, can_bubble, cancelable);
        }
        self.view.assign(view);
        self.detail = detail;
    }

    fn LayerX(&self) -> i32 {
        //TODO
        0
    }

    fn LayerY(&self) -> i32 {
        //TODO
        0
    }

    fn PageX(&self) -> i32 {
        //TODO
        0
    }

    fn PageY(&self) -> i32 {
        //TODO
        0
    }

    fn Which(&self) -> u32 {
        //TODO
        0
    }

    fn GetRangeParent(&self) -> Option<Temporary<Node>> {
        //TODO
        None
    }

    fn RangeOffset(&self) -> i32 {
        //TODO
        0
    }

    fn CancelBubble(&self) -> bool {
        //TODO
        false
    }

    fn SetCancelBubble(&self, _val: bool) {
        //TODO
    }

    fn IsChar(&self) -> bool {
        //TODO
        false
    }
}

impl Reflectable for UIEvent {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        self.event.reflector()
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        self.event.mut_reflector()
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 Dmytro Milinevskyi <dmilinevskyi@gmail.com>

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate bencher;

#[macro_use]
extern crate woodpecker;

mod wpb {
    use bencher::Bencher;
    use woodpecker as wp;

    use std::thread;
    use std::sync::Arc;
    use std::sync::atomic::{AtomicBool, Ordering};
    use std::sync::{Once, ONCE_INIT};

    static ONCE: Once = ONCE_INIT;
    const THREADS_QTY: usize = 4;
    const FOO_LOGGERS_QTY: usize = 10;

    struct LThreads {
        threads: Vec<thread::JoinHandle<()>>,
        stop: Arc<AtomicBool>,
    }

    impl LThreads {
        fn new(f: Arc<Fn() + Sync + Send>) -> Self {
            let mut threads = Vec::new();
            let stop = Arc::new(AtomicBool::new(false));
            for _ in 0..THREADS_QTY {
                let stop = stop.clone();
                let f = f.clone();
                threads.push(thread::spawn(move || {
                    while !stop.load(Ordering::Acquire) {
                        thread::yield_now();
                        f();
                    }
                }));
            }
            LThreads {
                threads: threads,
                stop: stop,
            }
        }

        fn join(&mut self) {
            self.stop.store(true, Ordering::Release);
            for t in self.threads.drain(..) {
                t.join().unwrap();
            }
        }
    }

    impl Drop for LThreads {
        fn drop(&mut self) {
            self.join();
        }
    }

    macro_rules! jail {
        ($b:ident, $body:expr) => {
            reset();
            $b.iter(|| { $body; });
        };
        ($b:ident, $pre:expr, $body:expr) => {
            reset();
            $pre;
            $b.iter(|| { $body; });
        };
    }

    macro_rules! tjail {
        ($b:ident, $body:expr) => {
            reset();
            let t = LThreads::new(Arc::new(|| { $body; }));
            $b.iter(|| { $body; });
            drop(t);
        };
        ($b:ident, $pre:expr, $body:expr) => {
            reset();
            $pre;
            let t = LThreads::new(Arc::new(|| { $body; }));
            $b.iter(|| { $body; });
            drop(t);
        };
    }

    macro_rules! doutput {
        () => { debug!("{:?} -> {}", thread::current(), "test") }
    }

    macro_rules! coutput {
        () => { critical!("{:?} -> {}", thread::current(), "test") }
    }

    fn reset() {
        ONCE.call_once(|| { wp::logger::init(); });
        wp::logger::reset();
        wp_set_level!(wp::LogLevel::ERROR);
    }

    fn drop_output() {
        wp_register_handler!(Box::new(|_| {}));
    }

    fn foo_loggers() {
        for idx in 0..FOO_LOGGERS_QTY {
            wp_set_level!(format!("foo::bar::qux::{}", idx), wp::LogLevel::DEBUG);
        }
    }

    fn foo_loggers_this_module() {
        foo_loggers();
        wp_set_level!(this_module!(), wp::LogLevel::INFO);
    }

    fn foo_loggers_this_file() {
        foo_loggers();
        wp_set_level!(this_file!(), wp::LogLevel::INFO);
    }

    // No output, single thread
    fn bench_no_output_single_thread(b: &mut Bencher) {
        jail!(
            b,
            doutput!()
        );
    }

    fn bench_no_output_sub_other_single_thread(b: &mut Bencher) {
        jail!(
            b,
            foo_loggers(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_module_single_thread(b: &mut Bencher) {
        jail!(
            b,
            foo_loggers_this_module(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_file_single_thread(b: &mut Bencher) {
        jail!(
            b,
            foo_loggers_this_file(),
            doutput!()
        );
    }

    // No output, multi thread
    fn bench_no_output_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            doutput!()
        );
    }

    fn bench_no_output_sub_other_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            foo_loggers(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_module_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            foo_loggers_this_module(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_file_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            foo_loggers_this_file(),
            doutput!()
        );
    }

    // Drop output, single thread
    fn bench_output_drop_single_thread(b: &mut Bencher) {
        jail!(
            b,
            drop_output(),
            coutput!()
        );
    }

    fn bench_output_drop_sub_other_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_output();
                foo_loggers();
            },
            coutput!()
        );
    }

    fn bench_output_drop_sub_this_module_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_output();
                foo_loggers_this_module();
            },
            coutput!()
        );
    }

    fn bench_output_drop_sub_this_file_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_output();
                foo_loggers_this_file();
            },
            coutput!()
        );
    }

    // Drop output, multi thread
    fn bench_output_drop_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            drop_output(),
            coutput!()
        );
    }

    fn bench_output_drop_sub_other_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_output();
                foo_loggers();
            },
            coutput!()
        );
    }

    fn bench_output_drop_sub_this_module_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_output();
                foo_loggers_this_module();
            },
            coutput!()
        );
    }

    fn bench_output_drop_sub_this_file_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_output();
                foo_loggers_this_file();
            },
            coutput!()
        );
    }

    fn bench_stub(_: &mut Bencher) {
    }

    benchmark_group!(
        benches,

        bench_no_output_single_thread,
        bench_no_output_sub_this_file_single_thread,
        bench_no_output_sub_this_module_single_thread,
        bench_no_output_sub_other_single_thread,

        bench_output_drop_single_thread,
        bench_output_drop_sub_this_module_single_thread,
        bench_output_drop_sub_this_file_single_thread,
        bench_output_drop_sub_other_single_thread,

        bench_no_output_multi_thread,
        bench_no_output_sub_this_file_multi_thread,
        bench_no_output_sub_this_module_multi_thread,
        bench_no_output_sub_other_multi_thread,

        bench_output_drop_multi_thread,
        bench_output_drop_sub_this_module_multi_thread,
        bench_output_drop_sub_this_file_multi_thread,
        bench_output_drop_sub_other_multi_thread,

        bench_stub
    );
}
benchmark_main!(wpb::benches);
<commit_msg>benches: bench format function<commit_after>// Copyright 2017 Dmytro Milinevskyi <dmilinevskyi@gmail.com>

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate bencher;

#[macro_use]
extern crate woodpecker;

mod wpb {
    use bencher::Bencher;
    use woodpecker as wp;

    use std::thread;
    use std::sync::Arc;
    use std::sync::atomic::{AtomicBool, Ordering};
    use std::sync::{Once, ONCE_INIT};

    static ONCE: Once = ONCE_INIT;
    const THREADS_QTY: usize = 4;
    const FOO_LOGGERS_QTY: usize = 10;

    struct LThreads {
        threads: Vec<thread::JoinHandle<()>>,
        stop: Arc<AtomicBool>,
    }

    impl LThreads {
        fn new(f: Arc<Fn() + Sync + Send>) -> Self {
            let mut threads = Vec::new();
            let stop = Arc::new(AtomicBool::new(false));
            for _ in 0..THREADS_QTY {
                let stop = stop.clone();
                let f = f.clone();
                threads.push(thread::spawn(move || {
                    while !stop.load(Ordering::Acquire) {
                        thread::yield_now();
                        f();
                    }
                }));
            }
            LThreads {
                threads: threads,
                stop: stop,
            }
        }

        fn join(&mut self) {
            self.stop.store(true, Ordering::Release);
            for t in self.threads.drain(..) {
                t.join().unwrap();
            }
        }
    }

    impl Drop for LThreads {
        fn drop(&mut self) {
            self.join();
        }
    }

    macro_rules! jail {
        ($b:ident, $body:expr) => {
            reset();
            $b.iter(|| { $body; });
        };
        ($b:ident, $pre:expr, $body:expr) => {
            reset();
            $pre;
            $b.iter(|| { $body; });
        };
    }

    macro_rules! tjail {
        ($b:ident, $body:expr) => {
            reset();
            let t = LThreads::new(Arc::new(|| { $body; }));
            $b.iter(|| { $body; });
            drop(t);
        };
        ($b:ident, $pre:expr, $body:expr) => {
            reset();
            $pre;
            let t = LThreads::new(Arc::new(|| { $body; }));
            $b.iter(|| { $body; });
            drop(t);
        };
    }

    macro_rules! doutput {
        () => { debug!("{} -> {}", "test", 1.0) }
    }

    macro_rules! coutput {
        () => { critical!("{} -> {}", "test", 1.0) }
    }

    fn reset() {
        ONCE.call_once(|| { wp::logger::init(); });
        wp::logger::reset();
        wp_set_level!(wp::LogLevel::ERROR);
    }

    fn drop_output() {
        wp_register_handler!(Box::new(|_| {}));
    }

    fn drop_formatted_output() {
        wp_register_handler!(Box::new(|r| {
            let _ = r.formatted();
        }));
    }

    fn foo_loggers() {
        for idx in 0..FOO_LOGGERS_QTY {
            wp_set_level!(format!("foo::bar::qux::{}", idx), wp::LogLevel::DEBUG);
        }
    }

    fn foo_loggers_this_module() {
        foo_loggers();
        wp_set_level!(this_module!(), wp::LogLevel::INFO);
    }

    fn foo_loggers_this_file() {
        foo_loggers();
        wp_set_level!(this_file!(), wp::LogLevel::INFO);
    }

    // No output, single thread
    fn bench_no_output_single_thread(b: &mut Bencher) {
        jail!(
            b,
            doutput!()
        );
    }

    fn bench_no_output_sub_other_single_thread(b: &mut Bencher) {
        jail!(
            b,
            foo_loggers(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_module_single_thread(b: &mut Bencher) {
        jail!(
            b,
            foo_loggers_this_module(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_file_single_thread(b: &mut Bencher) {
        jail!(
            b,
            foo_loggers_this_file(),
            doutput!()
        );
    }

    // No output, multi thread
    fn bench_no_output_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            doutput!()
        );
    }

    fn bench_no_output_sub_other_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            foo_loggers(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_module_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            foo_loggers_this_module(),
            doutput!()
        );
    }

    fn bench_no_output_sub_this_file_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            foo_loggers_this_file(),
            doutput!()
        );
    }

    // Drop output, single thread
    fn bench_drop_output_single_thread(b: &mut Bencher) {
        jail!(
            b,
            drop_output(),
            coutput!()
        );
    }

    fn bench_drop_output_sub_other_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_output();
                foo_loggers();
            },
            coutput!()
        );
    }

    fn bench_drop_output_sub_this_module_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_output();
                foo_loggers_this_module();
            },
            coutput!()
        );
    }

    fn bench_drop_output_sub_this_file_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_output();
                foo_loggers_this_file();
            },
            coutput!()
        );
    }

    // Drop output, multi thread
    fn bench_drop_output_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            drop_output(),
            coutput!()
        );
    }

    fn bench_drop_output_sub_other_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_output();
                foo_loggers();
            },
            coutput!()
        );
    }

    fn bench_drop_output_sub_this_module_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_output();
                foo_loggers_this_module();
            },
            coutput!()
        );
    }

    fn bench_drop_output_sub_this_file_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_output();
                foo_loggers_this_file();
            },
            coutput!()
        );
    }

    // Drop formatted output, single thread
    fn bench_drop_formatted_output_single_thread(b: &mut Bencher) {
        jail!(
            b,
            drop_formatted_output(),
            coutput!()
        );
    }

    fn bench_drop_formatted_output_sub_other_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_formatted_output();
                foo_loggers();
            },
            coutput!()
        );
    }

    fn bench_drop_formatted_output_sub_this_module_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_formatted_output();
                foo_loggers_this_module();
            },
            coutput!()
        );
    }

    fn bench_drop_formatted_output_sub_this_file_single_thread(b: &mut Bencher) {
        jail!(
            b,
            {
                drop_formatted_output();
                foo_loggers_this_file();
            },
            coutput!()
        );
    }

    // Drop formatted output, multi thread
    fn bench_drop_formatted_output_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            drop_formatted_output(),
            coutput!()
        );
    }

    fn bench_drop_formatted_output_sub_other_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_formatted_output();
                foo_loggers();
            },
            coutput!()
        );
    }

    fn bench_drop_formatted_output_sub_this_module_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_formatted_output();
                foo_loggers_this_module();
            },
            coutput!()
        );
    }

    fn bench_drop_formatted_output_sub_this_file_multi_thread(b: &mut Bencher) {
        tjail!(
            b,
            {
                drop_formatted_output();
                foo_loggers_this_file();
            },
            coutput!()
        );
    }

    fn bench_stub(_: &mut Bencher) {
    }

    benchmark_group!(
        benches,

        bench_no_output_single_thread,
        bench_no_output_sub_this_file_single_thread,
        bench_no_output_sub_this_module_single_thread,
        bench_no_output_sub_other_single_thread,

        bench_drop_output_single_thread,
        bench_drop_output_sub_this_module_single_thread,
        bench_drop_output_sub_this_file_single_thread,
        bench_drop_output_sub_other_single_thread,

        bench_drop_formatted_output_single_thread,
        bench_drop_formatted_output_sub_this_module_single_thread,
        bench_drop_formatted_output_sub_this_file_single_thread,
        bench_drop_formatted_output_sub_other_single_thread,

        bench_no_output_multi_thread,
        bench_no_output_sub_this_file_multi_thread,
        bench_no_output_sub_this_module_multi_thread,
        bench_no_output_sub_other_multi_thread,

        bench_drop_output_multi_thread,
        bench_drop_output_sub_this_module_multi_thread,
        bench_drop_output_sub_this_file_multi_thread,
        bench_drop_output_sub_other_multi_thread,

        bench_drop_formatted_output_multi_thread,
        bench_drop_formatted_output_sub_this_module_multi_thread,
        bench_drop_formatted_output_sub_this_file_multi_thread,
        bench_drop_formatted_output_sub_other_multi_thread,

        bench_stub
    );
}
benchmark_main!(wpb::benches);
<|endoftext|>


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

use std::str::FromStr;

use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError};
use hcore::fs;
use hcore::package::{PackageIdent, Identifiable};
use serde_json;

use super::super::RenderResult;

#[derive(Clone, Copy)]
pub struct PkgPathForHelper;

impl HelperDef for PkgPathForHelper {
    fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> RenderResult<()> {
        let param = h.param(0)
            .and_then(|v| v.value().as_str())
            .and_then(|v| PackageIdent::from_str(v).ok())
            .ok_or_else(|| {
                RenderError::new("Invalid package identifier for \"pkgPathFor\"")
            })?;
        let deps = serde_json::from_value::<Vec<PackageIdent>>(
            rc.context().data()["pkg"]["deps"].clone(),
        ).unwrap();
        let target_pkg = deps.iter()
            .find(|ident| ident.satisfies(&param))
            .and_then(|i| {
                Some(
                    fs::pkg_install_path(&i, None::<String>)
                        .to_string_lossy()
                        .into_owned(),
                )
            })
            .unwrap_or("".to_string());
        rc.writer.write(target_pkg.into_bytes().as_ref())?;
        Ok(())
    }
}

pub static PKG_PATH_FOR: PkgPathForHelper = PkgPathForHelper;
<commit_msg>prefix pkgPathFor with FS_ROOT`<commit_after>// Copyright (c) 2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::str::FromStr;

use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError};
use hcore::fs;
use hcore::package::{PackageIdent, Identifiable};
use serde_json;

use super::super::RenderResult;

#[derive(Clone, Copy)]
pub struct PkgPathForHelper;

impl HelperDef for PkgPathForHelper {
    fn call(&self, h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> RenderResult<()> {
        let param = h.param(0)
            .and_then(|v| v.value().as_str())
            .and_then(|v| PackageIdent::from_str(v).ok())
            .ok_or_else(|| {
                RenderError::new("Invalid package identifier for \"pkgPathFor\"")
            })?;
        let deps = serde_json::from_value::<Vec<PackageIdent>>(
            rc.context().data()["pkg"]["deps"].clone(),
        ).unwrap();
        let target_pkg = deps.iter()
            .find(|ident| ident.satisfies(&param))
            .and_then(|i| {
                Some(
                    fs::pkg_install_path(&i, Some(&*fs::FS_ROOT_PATH))
                        .to_string_lossy()
                        .into_owned(),
                )
            })
            .unwrap_or("".to_string());
        rc.writer.write(target_pkg.into_bytes().as_ref())?;
        Ok(())
    }
}

pub static PKG_PATH_FOR: PkgPathForHelper = PkgPathForHelper;
<|endoftext|>


<commit_before>// main.rs
// Main entry point for a Rust version
// of some (micro-) benchmarks
//
// vim: ft=rust sw=4 ts=4
//

extern crate image;
extern crate num;
extern crate num_complex;
extern crate rayon;
extern crate time;

use time::precise_time_ns;

// declare submodules
mod fibonacci;
mod mandelbrot;
mod perfect_number;

#[cfg(test)]
mod test {
    mod test_fib;
    mod test_pn;
}

// a helper function to time closures
fn time_it<F, T>(fun: F) -> (T, u64)
where
    F: Fn() -> T,
{
    let tic = precise_time_ns();
    let res = fun();
    let toc = precise_time_ns();

    (res, (toc - tic) / 1_000_000)
}

fn main() {
    println!("Rust benchmarks");
    println!("===============");

    println!();

    println!("Fibonacci numbers:");
    println!("------------------");

    let (res, elap) = time_it(|| fibonacci::fib_naive(35));
    println!("fib_naive(35) = {}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| fibonacci::fib(35));
    println!("fib(35) = {}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| fibonacci::fib(1000));
    println!("fib(1000) = {}\tElapsed: {}ms", res, elap);

    println!();

    println!("Perfect numbers:");
    println!("----------------");

    let (res, elap) = time_it(|| perfect_number::perfect_numbers(10000));
    println!("pn(10000) = {:?}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| perfect_number::perfect_number_iter(4));
    println!("pn_iter(4) = {:?}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| perfect_number::perfect_numbers_rayon(10000));
    println!("pn_rayon(10000) = {:?}\tElapsed: {}ms", res, elap);

    println!();

    println!("Mandelbrot set:");
    println!("--------------");

    let (res, elap) = time_it(|| mandelbrot::mandelbrot(640, 480, -0.5, 0.0, 4.0 / f64::from(640)));
    println!("mandelbrot(640, 480) done\tElapsed: {}ms", elap);
    let (_, elap) = time_it(|| res.save("./mandelbrot.png").unwrap());
    println!("mandelbrot(640, 480) written to PNG\tElapsed: {}ms", elap);

    let (res, elap) =
        time_it(|| mandelbrot::mandelbrot(1920, 1200, -0.5, 0.0, 4.0 / f64::from(1920)));
    println!("mandelbrot(1920, 1200) done\tElapsed: {}ms", elap);
    let (_, elap) = time_it(|| res.save("./mandelbrot.png").unwrap());
    println!("mandelbrot(1920, 1200) written to PNG\tElapsed: {}ms", elap);

    let _: Vec<()> = vec![1, 2, 4, 8, 16, 30, 40]
        .into_iter()
        .map(|i| {
            let (_res, elap) = time_it(|| {
                mandelbrot::mandelbrot_rayon(1920, 1200, -0.5, 0.0, 4.0 / f64::from(1920), i)
            });
            println!("mandelbrot_rayon(1920, 1200, {}) done\tElapsed: {}ms", i, elap);
        })
        .collect();

    let (_, elap) = time_it(|| res.save("./mandelbrot.png").unwrap());
    println!(
        "mandelbrot_rayon(1920, 1200) written to PNG\tElapsed: {}ms",
        elap
    );
    println!();

    println!("------------------");
    println!("Done!");
}
<commit_msg>increase number of workers<commit_after>// main.rs
// Main entry point for a Rust version
// of some (micro-) benchmarks
//
// vim: ft=rust sw=4 ts=4
//

extern crate image;
extern crate num;
extern crate num_complex;
extern crate rayon;
extern crate time;

use time::precise_time_ns;

// declare submodules
mod fibonacci;
mod mandelbrot;
mod perfect_number;

#[cfg(test)]
mod test {
    mod test_fib;
    mod test_pn;
}

// a helper function to time closures
fn time_it<F, T>(fun: F) -> (T, u64)
where
    F: Fn() -> T,
{
    let tic = precise_time_ns();
    let res = fun();
    let toc = precise_time_ns();

    (res, (toc - tic) / 1_000_000)
}

fn main() {
    println!("Rust benchmarks");
    println!("===============");

    println!();

    println!("Fibonacci numbers:");
    println!("------------------");

    let (res, elap) = time_it(|| fibonacci::fib_naive(35));
    println!("fib_naive(35) = {}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| fibonacci::fib(35));
    println!("fib(35) = {}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| fibonacci::fib(1000));
    println!("fib(1000) = {}\tElapsed: {}ms", res, elap);

    println!();

    println!("Perfect numbers:");
    println!("----------------");

    let (res, elap) = time_it(|| perfect_number::perfect_numbers(10000));
    println!("pn(10000) = {:?}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| perfect_number::perfect_number_iter(4));
    println!("pn_iter(4) = {:?}\tElapsed: {}ms", res, elap);

    let (res, elap) = time_it(|| perfect_number::perfect_numbers_rayon(10000));
    println!("pn_rayon(10000) = {:?}\tElapsed: {}ms", res, elap);

    println!();

    println!("Mandelbrot set:");
    println!("--------------");

    let (res, elap) = time_it(|| mandelbrot::mandelbrot(640, 480, -0.5, 0.0, 4.0 / f64::from(640)));
    println!("mandelbrot(640, 480) done\tElapsed: {}ms", elap);
    let (_, elap) = time_it(|| res.save("./mandelbrot.png").unwrap());
    println!("mandelbrot(640, 480) written to PNG\tElapsed: {}ms", elap);

    let (res, elap) =
        time_it(|| mandelbrot::mandelbrot(1920, 1200, -0.5, 0.0, 4.0 / f64::from(1920)));
    println!("mandelbrot(1920, 1200) done\tElapsed: {}ms", elap);
    let (_, elap) = time_it(|| res.save("./mandelbrot.png").unwrap());
    println!("mandelbrot(1920, 1200) written to PNG\tElapsed: {}ms", elap);

    let _: Vec<()> = vec![1, 2, 4, 8, 16, 30, 60]
        .into_iter()
        .map(|i| {
            let (_res, elap) = time_it(|| {
                mandelbrot::mandelbrot_rayon(1920, 1200, -0.5, 0.0, 4.0 / f64::from(1920), i)
            });
            println!("mandelbrot_rayon(1920, 1200, {}) done\tElapsed: {}ms", i, elap);
        })
        .collect();

    let (_, elap) = time_it(|| res.save("./mandelbrot.png").unwrap());
    println!(
        "mandelbrot_rayon(1920, 1200) written to PNG\tElapsed: {}ms",
        elap
    );
    println!();

    println!("------------------");
    println!("Done!");
}
<|endoftext|>