<commit_before>//! Shim which is passed to Cargo as "rustc" when running the bootstrap.
//!
//! This shim will take care of some various tasks that our build process
//! requires that Cargo can't quite do through normal configuration:
//!
//! 1. When compiling build scripts and build dependencies, we need a guaranteed
//!    full standard library available. The only compiler which actually has
//!    this is the snapshot, so we detect this situation and always compile with
//!    the snapshot compiler.
//! 2. We pass a bunch of `--cfg` and other flags based on what we're compiling
//!    (and this slightly differs based on a whether we're using a snapshot or
//!    not), so we do that all here.
//!
//! This may one day be replaced by RUSTFLAGS, but the dynamic nature of
//! switching compilers for the bootstrap and for build scripts will probably
//! never get replaced.

use std::env;
use std::io;
use std::path::PathBuf;
use std::process::Command;
use std::str::FromStr;
use std::time::Instant;

fn main() {
    let args = env::args_os().skip(1).collect::<Vec<_>>();

    // Detect whether or not we're a build script depending on whether --target
    // is passed (a bit janky...)
    let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str());
    let version = args.iter().find(|w| &**w == "-vV");

    let verbose = match env::var("RUSTC_VERBOSE") {
        Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"),
        Err(_) => 0,
    };

    // Use a different compiler for build scripts, since there may not yet be a
    // libstd for the real compiler to use. However, if Cargo is attempting to
    // determine the version of the compiler, the real compiler needs to be
    // used. Currently, these two states are differentiated based on whether
    // --target and -vV is/isn't passed.
    let (rustc, libdir) = if target.is_none() && version.is_none() {
        ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
    } else {
        ("RUSTC_REAL", "RUSTC_LIBDIR")
    };
    let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
    let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
    let on_fail = env::var_os("RUSTC_ON_FAIL").map(Command::new);

    let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
    let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
    let mut dylib_path = bootstrap::util::dylib_path();
    dylib_path.insert(0, PathBuf::from(&libdir));

    let mut cmd = Command::new(rustc);
    cmd.args(&args).env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap());

    // Get the name of the crate we're compiling, if any.
    let crate_name =
        args.windows(2).find(|args| args[0] == "--crate-name").and_then(|args| args[1].to_str());

    if let Some(crate_name) = crate_name {
        if let Some(target) = env::var_os("RUSTC_TIME") {
            if target == "all"
                || target.into_string().unwrap().split(',').any(|c| c.trim() == crate_name)
            {
                cmd.arg("-Ztime");
            }
        }
    }

    // Print backtrace in case of ICE
    if env::var("RUSTC_BACKTRACE_ON_ICE").is_ok() && env::var("RUST_BACKTRACE").is_err() {
        cmd.env("RUST_BACKTRACE", "1");
    }

    if let Ok(lint_flags) = env::var("RUSTC_LINT_FLAGS") {
        cmd.args(lint_flags.split_whitespace());
    }

    if target.is_some() {
        // The stage0 compiler has a special sysroot distinct from what we
        // actually downloaded, so we just always pass the `--sysroot` option,
        // unless one is already set.
        if !args.iter().any(|arg| arg == "--sysroot") {
            cmd.arg("--sysroot").arg(&sysroot);
        }

        // If we're compiling specifically the `panic_abort` crate then we pass
        // the `-C panic=abort` option. Note that we do not do this for any
        // other crate intentionally as this is the only crate for now that we
        // ship with panic=abort.
        //
        // This... is a bit of a hack how we detect this. Ideally this
        // information should be encoded in the crate I guess? Would likely
        // require an RFC amendment to RFC 1513, however.
        //
        // `compiler_builtins` are unconditionally compiled with panic=abort to
        // workaround undefined references to `rust_eh_unwind_resume` generated
        // otherwise, see issue https://github.com/rust-lang/rust/issues/43095.
        if crate_name == Some("panic_abort")
            || crate_name == Some("compiler_builtins") && stage != "0"
        {
            cmd.arg("-C").arg("panic=abort");
        }
    } else {
        // FIXME(rust-lang/cargo#5754) we shouldn't be using special env vars
        // here, but rather Cargo should know what flags to pass rustc itself.

        // Override linker if necessary.
        if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
            cmd.arg(format!("-Clinker={}", host_linker));
        }

        if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
            if s == "true" {
                cmd.arg("-C").arg("target-feature=+crt-static");
            }
            if s == "false" {
                cmd.arg("-C").arg("target-feature=-crt-static");
            }
        }
    }

    if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
        cmd.arg("--remap-path-prefix").arg(&map);
    }

    // Force all crates compiled by this compiler to (a) be unstable and (b)
    // allow the `rustc_private` feature to link to other unstable crates
    // also in the sysroot. We also do this for host crates, since those
    // may be proc macros, in which case we might ship them.
    if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() && (stage != "0" || target.is_some()) {
        cmd.arg("-Z").arg("force-unstable-if-unmarked");
    }

    if verbose > 1 {
        eprintln!(
            "rustc command: {:?}={:?} {:?}",
            bootstrap::util::dylib_path_var(),
            env::join_paths(&dylib_path).unwrap(),
            cmd,
        );
        eprintln!("sysroot: {:?}", sysroot);
        eprintln!("libdir: {:?}", libdir);
    }

    if let Some(mut on_fail) = on_fail {
        let e = match cmd.status() {
            Ok(s) if s.success() => std::process::exit(0),
            e => e,
        };
        println!("\nDid not run successfully: {}\n{:?}\n-------------", e, cmd);
        status_code(&mut on_fail).expect("could not run the backup command");
        std::process::exit(1);
    }

    if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() {
        if let Some(crate_name) = crate_name {
            let start = Instant::now();
            let status = cmd.status().unwrap_or_else(|_| panic!("\n\n failed to run {:?}", cmd));
            let dur = start.elapsed();

            let is_test = args.iter().any(|a| a == "--test");
            eprintln!(
                "[RUSTC-TIMING] {} test:{} {}.{:03}",
                crate_name,
                is_test,
                dur.as_secs(),
                dur.subsec_millis()
            );

            match status.code() {
                Some(i) => std::process::exit(i),
                None => {
                    eprintln!("rustc exited with {}", status);
                    std::process::exit(0xfe);
                }
            }
        }
    }

    let code = status_code(&mut cmd).unwrap_or_else(|_| panic!("\n\n failed to run {:?}", cmd));
    std::process::exit(code);
}

fn status_code(cmd: &mut Command) -> io::Result<i32> {
    cmd.status().map(|status| status.code().unwrap())
}
<commit_msg>rustbuild: format both Ok/Err separately, since Result doesn't do it<commit_after>//! Shim which is passed to Cargo as "rustc" when running the bootstrap.
//!
//! This shim will take care of some various tasks that our build process
//! requires that Cargo can't quite do through normal configuration:
//!
//! 1. When compiling build scripts and build dependencies, we need a guaranteed
//!    full standard library available. The only compiler which actually has
//!    this is the snapshot, so we detect this situation and always compile with
//!    the snapshot compiler.
//! 2. We pass a bunch of `--cfg` and other flags based on what we're compiling
//!    (and this slightly differs based on a whether we're using a snapshot or
//!    not), so we do that all here.
//!
//! This may one day be replaced by RUSTFLAGS, but the dynamic nature of
//! switching compilers for the bootstrap and for build scripts will probably
//! never get replaced.

use std::env;
use std::io;
use std::path::PathBuf;
use std::process::Command;
use std::str::FromStr;
use std::time::Instant;

fn main() {
    let args = env::args_os().skip(1).collect::<Vec<_>>();

    // Detect whether or not we're a build script depending on whether --target
    // is passed (a bit janky...)
    let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str());
    let version = args.iter().find(|w| &**w == "-vV");

    let verbose = match env::var("RUSTC_VERBOSE") {
        Ok(s) => usize::from_str(&s).expect("RUSTC_VERBOSE should be an integer"),
        Err(_) => 0,
    };

    // Use a different compiler for build scripts, since there may not yet be a
    // libstd for the real compiler to use. However, if Cargo is attempting to
    // determine the version of the compiler, the real compiler needs to be
    // used. Currently, these two states are differentiated based on whether
    // --target and -vV is/isn't passed.
    let (rustc, libdir) = if target.is_none() && version.is_none() {
        ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
    } else {
        ("RUSTC_REAL", "RUSTC_LIBDIR")
    };
    let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
    let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
    let on_fail = env::var_os("RUSTC_ON_FAIL").map(Command::new);

    let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
    let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
    let mut dylib_path = bootstrap::util::dylib_path();
    dylib_path.insert(0, PathBuf::from(&libdir));

    let mut cmd = Command::new(rustc);
    cmd.args(&args).env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap());

    // Get the name of the crate we're compiling, if any.
    let crate_name =
        args.windows(2).find(|args| args[0] == "--crate-name").and_then(|args| args[1].to_str());

    if let Some(crate_name) = crate_name {
        if let Some(target) = env::var_os("RUSTC_TIME") {
            if target == "all"
                || target.into_string().unwrap().split(',').any(|c| c.trim() == crate_name)
            {
                cmd.arg("-Ztime");
            }
        }
    }

    // Print backtrace in case of ICE
    if env::var("RUSTC_BACKTRACE_ON_ICE").is_ok() && env::var("RUST_BACKTRACE").is_err() {
        cmd.env("RUST_BACKTRACE", "1");
    }

    if let Ok(lint_flags) = env::var("RUSTC_LINT_FLAGS") {
        cmd.args(lint_flags.split_whitespace());
    }

    if target.is_some() {
        // The stage0 compiler has a special sysroot distinct from what we
        // actually downloaded, so we just always pass the `--sysroot` option,
        // unless one is already set.
        if !args.iter().any(|arg| arg == "--sysroot") {
            cmd.arg("--sysroot").arg(&sysroot);
        }

        // If we're compiling specifically the `panic_abort` crate then we pass
        // the `-C panic=abort` option. Note that we do not do this for any
        // other crate intentionally as this is the only crate for now that we
        // ship with panic=abort.
        //
        // This... is a bit of a hack how we detect this. Ideally this
        // information should be encoded in the crate I guess? Would likely
        // require an RFC amendment to RFC 1513, however.
        //
        // `compiler_builtins` are unconditionally compiled with panic=abort to
        // workaround undefined references to `rust_eh_unwind_resume` generated
        // otherwise, see issue https://github.com/rust-lang/rust/issues/43095.
        if crate_name == Some("panic_abort")
            || crate_name == Some("compiler_builtins") && stage != "0"
        {
            cmd.arg("-C").arg("panic=abort");
        }
    } else {
        // FIXME(rust-lang/cargo#5754) we shouldn't be using special env vars
        // here, but rather Cargo should know what flags to pass rustc itself.

        // Override linker if necessary.
        if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
            cmd.arg(format!("-Clinker={}", host_linker));
        }

        if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
            if s == "true" {
                cmd.arg("-C").arg("target-feature=+crt-static");
            }
            if s == "false" {
                cmd.arg("-C").arg("target-feature=-crt-static");
            }
        }
    }

    if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
        cmd.arg("--remap-path-prefix").arg(&map);
    }

    // Force all crates compiled by this compiler to (a) be unstable and (b)
    // allow the `rustc_private` feature to link to other unstable crates
    // also in the sysroot. We also do this for host crates, since those
    // may be proc macros, in which case we might ship them.
    if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() && (stage != "0" || target.is_some()) {
        cmd.arg("-Z").arg("force-unstable-if-unmarked");
    }

    if verbose > 1 {
        eprintln!(
            "rustc command: {:?}={:?} {:?}",
            bootstrap::util::dylib_path_var(),
            env::join_paths(&dylib_path).unwrap(),
            cmd,
        );
        eprintln!("sysroot: {:?}", sysroot);
        eprintln!("libdir: {:?}", libdir);
    }

    if let Some(mut on_fail) = on_fail {
        let e = match cmd.status() {
            Ok(s) => if s.success() { std::process::exit(0) } else { format!("Ok({})", s) },
            Err(e) => format!("Err({})", e),
        };
        println!("\nDid not run successfully: {}\n{:?}\n-------------", e, cmd);
        status_code(&mut on_fail).expect("could not run the backup command");
        std::process::exit(1);
    }

    if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() {
        if let Some(crate_name) = crate_name {
            let start = Instant::now();
            let status = cmd.status().unwrap_or_else(|_| panic!("\n\n failed to run {:?}", cmd));
            let dur = start.elapsed();

            let is_test = args.iter().any(|a| a == "--test");
            eprintln!(
                "[RUSTC-TIMING] {} test:{} {}.{:03}",
                crate_name,
                is_test,
                dur.as_secs(),
                dur.subsec_millis()
            );

            match status.code() {
                Some(i) => std::process::exit(i),
                None => {
                    eprintln!("rustc exited with {}", status);
                    std::process::exit(0xfe);
                }
            }
        }
    }

    let code = status_code(&mut cmd).unwrap_or_else(|_| panic!("\n\n failed to run {:?}", cmd));
    std::process::exit(code);
}

fn status_code(cmd: &mut Command) -> io::Result<i32> {
    cmd.status().map(|status| status.code().unwrap())
}
<|endoftext|>


<commit_before>use failure::Error;
use MAL;
use reqwest::{RequestBuilder, Response, Url};
use reqwest::header::{ContentType, Headers};

pub type ID = u32;

#[derive(Debug)]
pub enum RequestURL<'a> {
    AnimeList(&'a str),
    Search(&'a str),
    Add(ID),
    Update(ID),
}

impl<'a> RequestURL<'a> {
    pub const BASE_URL: &'static str = "https://myanimelist.net";
}

impl<'a> ToString for RequestURL<'a> {
    fn to_string(&self) -> String {
        let mut url = Url::parse(RequestURL::BASE_URL).unwrap();

        match *self {
            RequestURL::AnimeList(ref uname) => {
                url.set_path("/malappinfo.php");

                url.query_pairs_mut()
                    .append_pair("u", &uname)
                    .append_pair("status", "all")
                    .append_pair("type", "anime");
            }
            RequestURL::Search(ref name) => {
                url.set_path("/api/anime/search.xml");
                url.query_pairs_mut().append_pair("q", &name);
            }
            RequestURL::Add(id) => {
                url.set_path(&format!("/api/animelist/add/{}.xml", id));
            }
            RequestURL::Update(id) => {
                url.set_path(&format!("/api/animelist/update/{}.xml", id));
            }
        }

        url.into_string()
    }
}

#[derive(Fail, Debug)]
#[fail(display = "received bad response from MAL: {} {}", _0, _1)]
pub struct BadResponse(pub u16, pub String);

pub fn get(mal: &MAL, req_type: RequestURL) -> Result<Response, Error> {
    send_req(&mut mal.client.get(&req_type.to_string()))
}

pub fn send_req(req: &mut RequestBuilder) -> Result<Response, Error> {
    let resp = req.send()?;
    let status = resp.status();

    if status.is_success() {
        Ok(resp)
    } else {
        let reason = status.canonical_reason().unwrap_or("Unknown Error").into();
        Err(BadResponse(status.as_u16(), reason).into())
    }
}

pub fn auth_get(mal: &MAL, req_type: RequestURL) -> Result<Response, Error> {
    send_auth_req(mal, &mut mal.client.get(&req_type.to_string()))
}

pub fn auth_post(mal: &MAL, req_type: RequestURL, body: String) -> Result<Response, Error> {
    let mut headers = Headers::new();
    headers.set(ContentType::form_url_encoded());

    send_auth_req(
        mal,
        mal.client
            .post(&req_type.to_string())
            .body(format!("data={}", body))
            .headers(headers),
    )
}

fn send_auth_req(mal: &MAL, req: &mut RequestBuilder) -> Result<Response, Error> {
    send_req(req.basic_auth(mal.username.clone(), Some(mal.password.clone())))
}
<commit_msg>Explicitly match accepted API response codes to avoid ones like 204 slipping through<commit_after>use failure::Error;
use MAL;
use reqwest::{RequestBuilder, Response, StatusCode, Url};
use reqwest::header::{ContentType, Headers};

pub type ID = u32;

#[derive(Debug)]
pub enum RequestURL<'a> {
    AnimeList(&'a str),
    Search(&'a str),
    Add(ID),
    Update(ID),
}

impl<'a> RequestURL<'a> {
    pub const BASE_URL: &'static str = "https://myanimelist.net";
}

impl<'a> ToString for RequestURL<'a> {
    fn to_string(&self) -> String {
        let mut url = Url::parse(RequestURL::BASE_URL).unwrap();

        match *self {
            RequestURL::AnimeList(ref uname) => {
                url.set_path("/malappinfo.php");

                url.query_pairs_mut()
                    .append_pair("u", &uname)
                    .append_pair("status", "all")
                    .append_pair("type", "anime");
            }
            RequestURL::Search(ref name) => {
                url.set_path("/api/anime/search.xml");
                url.query_pairs_mut().append_pair("q", &name);
            }
            RequestURL::Add(id) => {
                url.set_path(&format!("/api/animelist/add/{}.xml", id));
            }
            RequestURL::Update(id) => {
                url.set_path(&format!("/api/animelist/update/{}.xml", id));
            }
        }

        url.into_string()
    }
}

#[derive(Fail, Debug)]
#[fail(display = "received bad response from MAL: {} {}", _0, _1)]
pub struct BadResponse(pub u16, pub String);

pub fn get(mal: &MAL, req_type: RequestURL) -> Result<Response, Error> {
    send_req(&mut mal.client.get(&req_type.to_string()))
}

pub fn send_req(req: &mut RequestBuilder) -> Result<Response, Error> {
    let resp = req.send()?;
    let status = resp.status();

    match status {
        StatusCode::Ok | StatusCode::Created => Ok(resp),
        _ => {
            let reason = status.canonical_reason().unwrap_or("Unknown Error").into();
            Err(BadResponse(status.as_u16(), reason).into())
        }
    }
}

pub fn auth_get(mal: &MAL, req_type: RequestURL) -> Result<Response, Error> {
    send_auth_req(mal, &mut mal.client.get(&req_type.to_string()))
}

pub fn auth_post(mal: &MAL, req_type: RequestURL, body: String) -> Result<Response, Error> {
    let mut headers = Headers::new();
    headers.set(ContentType::form_url_encoded());

    send_auth_req(
        mal,
        mal.client
            .post(&req_type.to_string())
            .body(format!("data={}", body))
            .headers(headers),
    )
}

fn send_auth_req(mal: &MAL, req: &mut RequestBuilder) -> Result<Response, Error> {
    send_req(req.basic_auth(mal.username.clone(), Some(mal.password.clone())))
}
<|endoftext|>


<commit_before><commit_msg>Add support for archiving threads<commit_after><|endoftext|>


<commit_before>use crate::internal::prelude::*;
use crate::model::id::{ChannelId, RoleId};
use std::collections::HashMap;

/// A builder which edits the properties of a [`Member`], to be used in
/// conjunction with [`Member::edit`].
///
/// [`Member`]: ../model/guild/struct.Member.html
/// [`Member::edit`]: ../model/guild/struct.Member.html#method.edit
#[derive(Clone, Debug, Default)]
pub struct EditMember(pub HashMap<&'static str, Value>);

impl EditMember {
    /// Whether to deafen the member.
    ///
    /// Requires the [Deafen Members] permission.
    ///
    /// [Deafen Members]: ../model/permissions/struct.Permissions.html#associatedconstant.DEAFEN_MEMBERS
    pub fn deafen(&mut self, deafen: bool) -> &mut Self {
        self.0.insert("deaf", Value::Bool(deafen));
        self
    }

    /// Whether to mute the member.
    ///
    /// Requires the [Mute Members] permission.
    ///
    /// [Mute Members]: ../model/permissions/struct.Permissions.html#associatedconstant.MUTE_MEMBERS
    pub fn mute(&mut self, mute: bool) -> &mut Self {
        self.0.insert("mute", Value::Bool(mute));
        self
    }

    /// Changes the member's nickname. Pass an empty string to reset the
    /// nickname.
    ///
    /// Requires the [Manage Nicknames] permission.
    ///
    /// [Manage Nicknames]: ../model/permissions/struct.Permissions.html#associatedconstant.MANAGE_NICKNAMES
    pub fn nickname<S: ToString>(&mut self, nickname: S) -> &mut Self {
        self.0.insert("nick", Value::String(nickname.to_string()));
        self
    }

    /// Set the list of roles that the member should have.
    ///
    /// Requires the [Manage Roles] permission to modify.
    ///
    /// [Manage Roles]: ../model/permissions/struct.Permissions.html#associatedconstant.MANAGE_ROLES
    pub fn roles<T: AsRef<RoleId>, It: IntoIterator<Item=T>>(&mut self, roles: It) -> &mut Self {
        let role_ids = roles
            .into_iter()
            .map(|x| Value::Number(Number::from(x.as_ref().0)))
            .collect();

        self._roles(role_ids);
        self
    }

    fn _roles(&mut self, roles: Vec<Value>) {
        self.0.insert("roles", Value::Array(roles));
    }

    /// The Id of the voice channel to move the member to.
    ///
    /// Requires the [Move Members] permission.
    ///
    /// [Move Members]: ../model/permissions/struct.Permissions.html#associatedconstant.MOVE_MEMBERS
    #[inline]
    pub fn voice_channel<C: Into<ChannelId>>(&mut self, channel_id: C) {
        self._voice_channel(channel_id.into())
    }

    fn _voice_channel(&mut self, channel_id: ChannelId) {
        let num = Value::Number(Number::from(channel_id.0));
        self.0.insert("channel_id", num);
    }
}
<commit_msg>Return `&mut self` on `voice_channel`. (#587)<commit_after>use crate::internal::prelude::*;
use crate::model::id::{ChannelId, RoleId};
use std::collections::HashMap;

/// A builder which edits the properties of a [`Member`], to be used in
/// conjunction with [`Member::edit`].
///
/// [`Member`]: ../model/guild/struct.Member.html
/// [`Member::edit`]: ../model/guild/struct.Member.html#method.edit
#[derive(Clone, Debug, Default)]
pub struct EditMember(pub HashMap<&'static str, Value>);

impl EditMember {
    /// Whether to deafen the member.
    ///
    /// Requires the [Deafen Members] permission.
    ///
    /// [Deafen Members]: ../model/permissions/struct.Permissions.html#associatedconstant.DEAFEN_MEMBERS
    pub fn deafen(&mut self, deafen: bool) -> &mut Self {
        self.0.insert("deaf", Value::Bool(deafen));
        self
    }

    /// Whether to mute the member.
    ///
    /// Requires the [Mute Members] permission.
    ///
    /// [Mute Members]: ../model/permissions/struct.Permissions.html#associatedconstant.MUTE_MEMBERS
    pub fn mute(&mut self, mute: bool) -> &mut Self {
        self.0.insert("mute", Value::Bool(mute));
        self
    }

    /// Changes the member's nickname. Pass an empty string to reset the
    /// nickname.
    ///
    /// Requires the [Manage Nicknames] permission.
    ///
    /// [Manage Nicknames]: ../model/permissions/struct.Permissions.html#associatedconstant.MANAGE_NICKNAMES
    pub fn nickname<S: ToString>(&mut self, nickname: S) -> &mut Self {
        self.0.insert("nick", Value::String(nickname.to_string()));
        self
    }

    /// Set the list of roles that the member should have.
    ///
    /// Requires the [Manage Roles] permission to modify.
    ///
    /// [Manage Roles]: ../model/permissions/struct.Permissions.html#associatedconstant.MANAGE_ROLES
    pub fn roles<T: AsRef<RoleId>, It: IntoIterator<Item=T>>(&mut self, roles: It) -> &mut Self {
        let role_ids = roles
            .into_iter()
            .map(|x| Value::Number(Number::from(x.as_ref().0)))
            .collect();

        self._roles(role_ids);
        self
    }

    fn _roles(&mut self, roles: Vec<Value>) {
        self.0.insert("roles", Value::Array(roles));
    }

    /// The Id of the voice channel to move the member to.
    ///
    /// Requires the [Move Members] permission.
    ///
    /// [Move Members]: ../model/permissions/struct.Permissions.html#associatedconstant.MOVE_MEMBERS
    #[inline]
    pub fn voice_channel<C: Into<ChannelId>>(&mut self, channel_id: C) -> &mut Self {
        self._voice_channel(channel_id.into());

        self
    }

    fn _voice_channel(&mut self, channel_id: ChannelId) {
        let num = Value::Number(Number::from(channel_id.0));
        self.0.insert("channel_id", num);
    }
}
<|endoftext|>


<commit_before>#![allow(non_snake_case, non_upper_case_globals)]
extern crate time;
use time::precise_time_s;

///////////////////////////////////////////////////////////////////////////////
// 1. Calibration
///////////////////////////////////////////////////////////////////////////////
const aalpha:f64 = 0.33333333333;  // Elasticity of output w.r.t. capital
const bbeta:f64 = 0.95;           // Discount factor

// Productivity values
const vProductivity:[f64; 5] = [0.9792, 0.9896, 1.0000, 1.0106, 1.0212];

// Transition matrix
const mTransition:[[f64; 5]; 5] = [
    [0.9727, 0.0273, 0.0000, 0.0000, 0.0000],
    [0.0041, 0.9806, 0.0153, 0.0000, 0.0000],
    [0.0000, 0.0082, 0.9837, 0.0082, 0.0000],
    [0.0000, 0.0000, 0.0153, 0.9806, 0.0041],
    [0.0000, 0.0000, 0.0000, 0.0273, 0.9727]
];

// Dimensions to generate the grid of capital
const nGridCapital: usize = 17820;
const nGridProductivity: usize = 5;

fn main() {

  let cpu0 = precise_time_s();

  /////////////////////////////////////////////////////////////////////////////
  // 2. Steady State
  /////////////////////////////////////////////////////////////////////////////

  let capitalSteadyState:f64 = (aalpha*bbeta).powf(1_f64/(1_f64-aalpha));
  let outputSteadyState:f64  = capitalSteadyState.powf(aalpha);
  let consumptionSteadyState:f64 = outputSteadyState-capitalSteadyState;

  println!("\
    Output = {}, Capital = {}, Consumption = {}",
    outputSteadyState, capitalSteadyState, consumptionSteadyState);

  let mut vGridCapital: [f64; nGridCapital] = [0_f64; nGridCapital];

  for nCapital in 0..nGridCapital {
      vGridCapital[nCapital] = 0.5*capitalSteadyState + 0.00001*(nCapital as f64)
  }

  // 3. Required matrices and vectors
  fn row() -> Vec<f64> {
    (0..nGridProductivity).map(|_| 0_f64).collect::<Vec<f64>>()
  }

  let mut mOutput = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
  let mut mValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
  let mut mValueFunctionNew = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
  let mut mPolicyFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
  let mut expectedValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();

  // 4. We pre-build output for each point in the grid

  for nProductivity in 0..nGridProductivity {
    for nCapital in 0..nGridCapital {
        mOutput[nCapital][nProductivity] = vProductivity[nProductivity]*vGridCapital[nCapital].powf(aalpha);
    }
  }

  // 5. Main iteration
  // TODO: one could implement a macro for the multiple declarations
  let mut maxDifference = 10_f64;
  let mut diff: f64;
  let mut diffHighSoFar: f64;
  let tolerance = 0.0000001_f64; // compiler warn: variable does not need to be mutable
  let mut valueHighSoFar: f64;
  let mut valueProvisional: f64;
  let mut consumption: f64;
  let mut capitalChoice: f64;

  let mut iteration = 0;

  while maxDifference > tolerance {

    for nProductivity in 0..nGridProductivity {
        for nCapital in 0..nGridCapital {
            expectedValueFunction[nCapital][nProductivity] = 0.0;
            for nProductivityNextPeriod in 0..nGridProductivity {
                expectedValueFunction[nCapital][nProductivity] += mTransition[nProductivity][nProductivityNextPeriod]*mValueFunction[nCapital][nProductivityNextPeriod];
            }
        }
    }

    for nProductivity in 0..nGridProductivity {

        // We start from previous choice (monotonicity of policy function)
        let mut gridCapitalNextPeriod = 0;

        for nCapital in 0..nGridCapital {

            valueHighSoFar = -100000.0;
            //capitalChoice  = vGridCapital[0]; // compiler warn: is never read

            for nCapitalNextPeriod in gridCapitalNextPeriod..nGridCapital {

                consumption = mOutput[nCapital][nProductivity]-vGridCapital[nCapitalNextPeriod];
                valueProvisional = (1_f64-bbeta)*(consumption.ln())+bbeta*expectedValueFunction[nCapitalNextPeriod][nProductivity];

                if valueProvisional>valueHighSoFar {
                    valueHighSoFar = valueProvisional;
                    capitalChoice = vGridCapital[nCapitalNextPeriod];
                    gridCapitalNextPeriod = nCapitalNextPeriod;
                }
                else{
                    break; // We break when we have achieved the max
                }

                mValueFunctionNew[nCapital][nProductivity] = valueHighSoFar;
                mPolicyFunction[nCapital][nProductivity] = capitalChoice;
            }

        }

    }

    diffHighSoFar = -100000.0;
    for nProductivity in 0..nGridProductivity {
        for nCapital in 0..nGridCapital {
            diff = (mValueFunction[nCapital][nProductivity]-mValueFunctionNew[nCapital][nProductivity]).abs();
            if diff>diffHighSoFar {
                diffHighSoFar = diff;
            }
            mValueFunction[nCapital][nProductivity] = mValueFunctionNew [nCapital][nProductivity];
        }
    }
    maxDifference = diffHighSoFar;

    iteration += 1;
    if iteration % 10 == 0 || iteration == 1 {
        println!("Iteration = {}, Sup Diff = {}", iteration, maxDifference);
    }
  }

  println!("Iteration = {}, Sup Diff = {}\n", iteration, maxDifference);
  println!("My check = {}\n", mPolicyFunction[999][2]);

  let cpu1 = precise_time_s();

  println!("Elapsed time is   = {}", cpu1  - cpu0);
}
<commit_msg>minor improvements<commit_after>#![allow(non_snake_case, non_upper_case_globals)]
extern crate time;
use time::precise_time_s;

///////////////////////////////////////////////////////////////////////////////
// 1. Calibration
///////////////////////////////////////////////////////////////////////////////
const aalpha:f64 = 0.33333333333;  // Elasticity of output w.r.t. capital
const bbeta:f64 = 0.95;           // Discount factor

// Productivity values
const vProductivity:[f64; 5] = [0.9792, 0.9896, 1.0000, 1.0106, 1.0212];

// Transition matrix
const mTransition:[[f64; 5]; 5] = [
    [0.9727, 0.0273, 0.0000, 0.0000, 0.0000],
    [0.0041, 0.9806, 0.0153, 0.0000, 0.0000],
    [0.0000, 0.0082, 0.9837, 0.0082, 0.0000],
    [0.0000, 0.0000, 0.0153, 0.9806, 0.0041],
    [0.0000, 0.0000, 0.0000, 0.0273, 0.9727]
];

// Dimensions to generate the grid of capital
const nGridCapital: usize = 17820;
const nGridProductivity: usize = 5;

fn main() {

  let cpu0 = precise_time_s();

  /////////////////////////////////////////////////////////////////////////////
  // 2. Steady State
  /////////////////////////////////////////////////////////////////////////////

  let capitalSteadyState:f64 = (aalpha*bbeta).powf(1_f64/(1_f64-aalpha));
  let outputSteadyState:f64  = capitalSteadyState.powf(aalpha);
  let consumptionSteadyState:f64 = outputSteadyState-capitalSteadyState;

  println!("\
    Output = {}, Capital = {}, Consumption = {}",
    outputSteadyState, capitalSteadyState, consumptionSteadyState);

  let vGridCapital = (0..nGridCapital).map(|nCapital|
    0.5*capitalSteadyState + 0.00001*(nCapital as f64)
  ).collect::<Vec<f64>>();

  // 3. Required matrices and vectors
  // One could use: vec![vec![0_f64; nGridProductivity]; nGridCapital];
  // but for some reasons this is faster.

  #[inline]
  fn row() -> Vec<f64> {
    (0..nGridProductivity).map(|_| 0_f64).collect::<Vec<f64>>()
  }

  let mut mValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
  let mut mValueFunctionNew = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
  let mut mPolicyFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();
  let mut expectedValueFunction = (0..nGridCapital).map(|_| row()).collect::<Vec<Vec<f64>>>();

  // 4. We pre-build output for each point in the grid
  let mOutput = (0..nGridCapital).map(|nCapital| {
    (0..nGridProductivity).map(|nProductivity|
        vProductivity[nProductivity]*vGridCapital[nCapital].powf(aalpha)
      ).collect::<Vec<f64>>()
  }).collect::<Vec<Vec<f64>>>();

  // 5. Main iteration
  // TODO: one could implement a macro for the multiple declarations
  let mut maxDifference = 10_f64;
  let mut diff: f64;
  let mut diffHighSoFar: f64;
  let tolerance = 0.0000001_f64; // compiler warn: variable does not need to be mutable
  let mut valueHighSoFar: f64;
  let mut valueProvisional: f64;
  let mut consumption: f64;
  let mut capitalChoice: f64;

  let mut iteration = 0;

  while maxDifference > tolerance {

    for nProductivity in 0..nGridProductivity {
        for nCapital in 0..nGridCapital {
            expectedValueFunction[nCapital][nProductivity] = 0.0;
            for nProductivityNextPeriod in 0..nGridProductivity {
                expectedValueFunction[nCapital][nProductivity] += mTransition[nProductivity][nProductivityNextPeriod]*mValueFunction[nCapital][nProductivityNextPeriod];
            }
        }
    }

    for nProductivity in 0..nGridProductivity {

        // We start from previous choice (monotonicity of policy function)
        let mut gridCapitalNextPeriod = 0;

        for nCapital in 0..nGridCapital {

            valueHighSoFar = -100000.0;
            //capitalChoice  = vGridCapital[0]; // compiler warn: is never read

            for nCapitalNextPeriod in gridCapitalNextPeriod..nGridCapital {

                consumption = mOutput[nCapital][nProductivity]-vGridCapital[nCapitalNextPeriod];
                valueProvisional = (1_f64-bbeta)*(consumption.ln())+bbeta*expectedValueFunction[nCapitalNextPeriod][nProductivity];

                if valueProvisional>valueHighSoFar {
                    valueHighSoFar = valueProvisional;
                    capitalChoice = vGridCapital[nCapitalNextPeriod];
                    gridCapitalNextPeriod = nCapitalNextPeriod;
                }
                else{
                    break; // We break when we have achieved the max
                }

                mValueFunctionNew[nCapital][nProductivity] = valueHighSoFar;
                mPolicyFunction[nCapital][nProductivity] = capitalChoice;
            }

        }

    }

    diffHighSoFar = -100000.0;
    for nProductivity in 0..nGridProductivity {
        for nCapital in 0..nGridCapital {
            diff = (mValueFunction[nCapital][nProductivity]-mValueFunctionNew[nCapital][nProductivity]).abs();
            if diff>diffHighSoFar {
                diffHighSoFar = diff;
            }
            mValueFunction[nCapital][nProductivity] = mValueFunctionNew[nCapital][nProductivity];
        }
    }
    maxDifference = diffHighSoFar;

    iteration += 1;
    if iteration % 10 == 0 || iteration == 1 {
        println!("Iteration = {}, Sup Diff = {}", iteration, maxDifference);
    }
  }

  println!("Iteration = {}, Sup Diff = {}\n", iteration, maxDifference);
  println!("My check = {}\n", mPolicyFunction[999][2]);

  let cpu1 = precise_time_s();

  println!("Elapsed time is   = {}", cpu1  - cpu0);
}
<|endoftext|>


<commit_before>use std::io::{Result, Write};

use super::super::general::write_vec;

pub fn begin<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#![allow(non_camel_case_types)]",
"#![allow(dead_code)]",
"",
"extern crate libc;",
"#[macro_use] extern crate bitflags;",
"",
"pub mod enums;",
    ];

    write_vec(w, &v)
}

pub fn after_extern_crates<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#[allow(unused_imports)]",
"use libc::{c_int, c_char, c_float, c_uint, c_double, c_long, c_void, size_t, ssize_t, time_t};",
"",
"pub use glib_ffi::{",
"    gboolean, GFALSE, GTRUE, gsize, gpointer, GType, GObject, GPermission,",
"    GList, GSList, GError, GValue};",
    ];

    write_vec(w, &v)
}

pub fn before_func<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"pub const GTK_ENTRY_BUFFER_MAX_SIZE: u16 = ::std::u16::MAX;",
"",
"//pub type GtkTreeModelForeachFunc = fn(model: *mut GtkTreeModel, path: *mut GtkTreePath, iter: *mut GtkTreeIter, data: gpointer) -> gboolean;",
"",
"pub const GTK_STYLE_PROVIDER_PRIORITY_FALLBACK: u32 = 1;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_THEME: u32 = 200;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_SETTINGS: u32 = 400;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_APPLICATION: u32 = 600;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_USER: u32 = 800;",
    ];

    write_vec(w, &v)
}
<commit_msg>Don't include enums.rs<commit_after>use std::io::{Result, Write};

use super::super::general::write_vec;

pub fn begin<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#![allow(non_camel_case_types)]",
"#![allow(dead_code)]",
"",
"extern crate libc;",
"#[macro_use] extern crate bitflags;",
    ];

    write_vec(w, &v)
}

pub fn after_extern_crates<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"",
"#[allow(unused_imports)]",
"use libc::{c_int, c_char, c_float, c_uint, c_double, c_long, c_void, size_t, ssize_t, time_t};",
"",
"pub use glib_ffi::{",
"    gboolean, GFALSE, GTRUE, gsize, gpointer, GType, GObject, GPermission,",
"    GList, GSList, GError, GValue};",
    ];

    write_vec(w, &v)
}

pub fn before_func<W: Write>(w: &mut W) -> Result<()>{
    let v = vec![
"pub const GTK_ENTRY_BUFFER_MAX_SIZE: u16 = ::std::u16::MAX;",
"",
"//pub type GtkTreeModelForeachFunc = fn(model: *mut GtkTreeModel, path: *mut GtkTreePath, iter: *mut GtkTreeIter, data: gpointer) -> gboolean;",
"",
"pub const GTK_STYLE_PROVIDER_PRIORITY_FALLBACK: u32 = 1;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_THEME: u32 = 200;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_SETTINGS: u32 = 400;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_APPLICATION: u32 = 600;",
"pub const GTK_STYLE_PROVIDER_PRIORITY_USER: u32 = 800;",
    ];

    write_vec(w, &v)
}
<|endoftext|>


<commit_before>

/*
 * The compiler code necessary to support the #fmt extension. Eventually this
 * should all get sucked into either the standard library extfmt module or the
 * compiler syntax extension plugin interface.
 */
import core::{vec, str, option};
import option::{some};
import extfmt::ct::*;
import base::*;
import codemap::span;
export expand_syntax_ext;

fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: @ast::expr,
                     _body: option::t<str>) -> @ast::expr {
    let args: [@ast::expr] =
        alt arg.node {
          ast::expr_vec(elts, _) { elts }
          _ {
            cx.span_fatal(sp, "#fmt requires arguments of the form `[...]`.")
          }
        };
    if vec::len::<@ast::expr>(args) == 0u {
        cx.span_fatal(sp, "#fmt requires a format string");
    }
    let fmt =
        expr_to_str(cx, args[0],
                    "first argument to #fmt must be a " + "string literal.");
    let fmtspan = args[0].span;
    log "Format string:";
    log fmt;
    fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: str) -> ! {
        cx.span_fatal(sp, msg);
    }
    let parse_fmt_err = bind parse_fmt_err_(cx, fmtspan, _);
    let pieces = parse_fmt_string(fmt, parse_fmt_err);
    ret pieces_to_expr(cx, sp, pieces, args);
}

// FIXME: A lot of these functions for producing expressions can probably
// be factored out in common with other code that builds expressions.
// FIXME: Cleanup the naming of these functions
fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
   -> @ast::expr {
    fn make_new_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
        let sp_lit = @{node: lit, span: sp};
        ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
    }
    fn make_new_str(cx: ext_ctxt, sp: span, s: str) -> @ast::expr {
        let lit = ast::lit_str(s);
        ret make_new_lit(cx, sp, lit);
    }
    fn make_new_int(cx: ext_ctxt, sp: span, i: int) -> @ast::expr {
        let lit = ast::lit_int(i as i64, ast::ty_i);
        ret make_new_lit(cx, sp, lit);
    }
    fn make_new_uint(cx: ext_ctxt, sp: span, u: uint) -> @ast::expr {
        let lit = ast::lit_uint(u as u64, ast::ty_u);
        ret make_new_lit(cx, sp, lit);
    }
    fn make_add_expr(cx: ext_ctxt, sp: span, lhs: @ast::expr, rhs: @ast::expr)
       -> @ast::expr {
        let binexpr = ast::expr_binary(ast::add, lhs, rhs);
        ret @{id: cx.next_id(), node: binexpr, span: sp};
    }
    fn make_path_expr(cx: ext_ctxt, sp: span, idents: [ast::ident]) ->
       @ast::expr {
        let path = {global: false, idents: idents, types: []};
        let sp_path = @{node: path, span: sp};
        let pathexpr = ast::expr_path(sp_path);
        ret @{id: cx.next_id(), node: pathexpr, span: sp};
    }
    fn make_vec_expr(cx: ext_ctxt, sp: span, exprs: [@ast::expr]) ->
       @ast::expr {
        let vecexpr = ast::expr_vec(exprs, ast::imm);
        ret @{id: cx.next_id(), node: vecexpr, span: sp};
    }
    fn make_call(cx: ext_ctxt, sp: span, fn_path: [ast::ident],
                 args: [@ast::expr]) -> @ast::expr {
        let pathexpr = make_path_expr(cx, sp, fn_path);
        let callexpr = ast::expr_call(pathexpr, args, false);
        ret @{id: cx.next_id(), node: callexpr, span: sp};
    }
    fn make_rec_expr(cx: ext_ctxt, sp: span,
                     fields: [{ident: ast::ident, ex: @ast::expr}]) ->
       @ast::expr {
        let astfields: [ast::field] = [];
        for field: {ident: ast::ident, ex: @ast::expr} in fields {
            let ident = field.ident;
            let val = field.ex;
            let astfield =
                {node: {mut: ast::imm, ident: ident, expr: val}, span: sp};
            astfields += [astfield];
        }
        let recexpr = ast::expr_rec(astfields, option::none::<@ast::expr>);
        ret @{id: cx.next_id(), node: recexpr, span: sp};
    }
    fn make_path_vec(cx: ext_ctxt, ident: ast::ident) -> [ast::ident] {
        fn compiling_std(cx: ext_ctxt) -> bool {
            ret str::find(cx.crate_file_name(), "std.rc") >= 0;
        }
        if compiling_std(cx) {
            ret ["extfmt", "rt", ident];
        } else { ret ["std", "extfmt", "rt", ident]; }
    }
    fn make_rt_path_expr(cx: ext_ctxt, sp: span, ident: str) -> @ast::expr {
        let path = make_path_vec(cx, ident);
        ret make_path_expr(cx, sp, path);
    }
    // Produces an AST expression that represents a RT::conv record,
    // which tells the RT::conv* functions how to perform the conversion

    fn make_rt_conv_expr(cx: ext_ctxt, sp: span, cnv: conv) -> @ast::expr {
        fn make_flags(cx: ext_ctxt, sp: span, flags: [flag]) -> @ast::expr {
            let flagexprs: [@ast::expr] = [];
            for f: flag in flags {
                let fstr;
                alt f {
                  flag_left_justify. { fstr = "flag_left_justify"; }
                  flag_left_zero_pad. { fstr = "flag_left_zero_pad"; }
                  flag_space_for_sign. { fstr = "flag_space_for_sign"; }
                  flag_sign_always. { fstr = "flag_sign_always"; }
                  flag_alternate. { fstr = "flag_alternate"; }
                }
                flagexprs += [make_rt_path_expr(cx, sp, fstr)];
            }
            // FIXME: 0-length vectors can't have their type inferred
            // through the rec that these flags are a member of, so
            // this is a hack placeholder flag

            if vec::len::<@ast::expr>(flagexprs) == 0u {
                flagexprs += [make_rt_path_expr(cx, sp, "flag_none")];
            }
            ret make_vec_expr(cx, sp, flagexprs);
        }
        fn make_count(cx: ext_ctxt, sp: span, cnt: count) -> @ast::expr {
            alt cnt {
              count_implied. {
                ret make_rt_path_expr(cx, sp, "count_implied");
              }
              count_is(c) {
                let count_lit = make_new_int(cx, sp, c);
                let count_is_path = make_path_vec(cx, "count_is");
                let count_is_args = [count_lit];
                ret make_call(cx, sp, count_is_path, count_is_args);
              }
              _ { cx.span_unimpl(sp, "unimplemented #fmt conversion"); }
            }
        }
        fn make_ty(cx: ext_ctxt, sp: span, t: ty) -> @ast::expr {
            let rt_type;
            alt t {
              ty_hex(c) {
                alt c {
                  case_upper. { rt_type = "ty_hex_upper"; }
                  case_lower. { rt_type = "ty_hex_lower"; }
                }
              }
              ty_bits. { rt_type = "ty_bits"; }
              ty_octal. { rt_type = "ty_octal"; }
              _ { rt_type = "ty_default"; }
            }
            ret make_rt_path_expr(cx, sp, rt_type);
        }
        fn make_conv_rec(cx: ext_ctxt, sp: span, flags_expr: @ast::expr,
                         width_expr: @ast::expr, precision_expr: @ast::expr,
                         ty_expr: @ast::expr) -> @ast::expr {
            ret make_rec_expr(cx, sp,
                              [{ident: "flags", ex: flags_expr},
                               {ident: "width", ex: width_expr},
                               {ident: "precision", ex: precision_expr},
                               {ident: "ty", ex: ty_expr}]);
        }
        let rt_conv_flags = make_flags(cx, sp, cnv.flags);
        let rt_conv_width = make_count(cx, sp, cnv.width);
        let rt_conv_precision = make_count(cx, sp, cnv.precision);
        let rt_conv_ty = make_ty(cx, sp, cnv.ty);
        ret make_conv_rec(cx, sp, rt_conv_flags, rt_conv_width,
                          rt_conv_precision, rt_conv_ty);
    }
    fn make_conv_call(cx: ext_ctxt, sp: span, conv_type: str, cnv: conv,
                      arg: @ast::expr) -> @ast::expr {
        let fname = "conv_" + conv_type;
        let path = make_path_vec(cx, fname);
        let cnv_expr = make_rt_conv_expr(cx, sp, cnv);
        let args = [cnv_expr, arg];
        ret make_call(cx, arg.span, path, args);
    }
    fn make_new_conv(cx: ext_ctxt, sp: span, cnv: conv, arg: @ast::expr) ->
       @ast::expr {
        // FIXME: Extract all this validation into extfmt::ct

        fn is_signed_type(cnv: conv) -> bool {
            alt cnv.ty {
              ty_int(s) {
                alt s { signed. { ret true; } unsigned. { ret false; } }
              }
              ty_float. { ret true; }
              _ { ret false; }
            }
        }
        let unsupported = "conversion not supported in #fmt string";
        alt cnv.param {
          option::none. { }
          _ { cx.span_unimpl(sp, unsupported); }
        }
        for f: flag in cnv.flags {
            alt f {
              flag_left_justify. { }
              flag_sign_always. {
                if !is_signed_type(cnv) {
                    cx.span_fatal(sp,
                                  "+ flag only valid in " +
                                      "signed #fmt conversion");
                }
              }
              flag_space_for_sign. {
                if !is_signed_type(cnv) {
                    cx.span_fatal(sp,
                                  "space flag only valid in " +
                                      "signed #fmt conversions");
                }
              }
              flag_left_zero_pad. { }
              _ { cx.span_unimpl(sp, unsupported); }
            }
        }
        alt cnv.width {
          count_implied. { }
          count_is(_) { }
          _ { cx.span_unimpl(sp, unsupported); }
        }
        alt cnv.precision {
          count_implied. { }
          count_is(_) { }
          _ { cx.span_unimpl(sp, unsupported); }
        }
        alt cnv.ty {
          ty_str. { ret make_conv_call(cx, arg.span, "str", cnv, arg); }
          ty_int(sign) {
            alt sign {
              signed. { ret make_conv_call(cx, arg.span, "int", cnv, arg); }
              unsigned. {
                ret make_conv_call(cx, arg.span, "uint", cnv, arg);
              }
            }
          }
          ty_bool. { ret make_conv_call(cx, arg.span, "bool", cnv, arg); }
          ty_char. { ret make_conv_call(cx, arg.span, "char", cnv, arg); }
          ty_hex(_) { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
          ty_bits. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
          ty_octal. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
          ty_float. { ret make_conv_call(cx, arg.span, "float", cnv, arg); }
          _ { cx.span_unimpl(sp, unsupported); }
        }
    }
    fn log_conv(c: conv) {
        alt c.param {
          some(p) { log "param: " + int::to_str(p, 10u); }
          _ { log "param: none"; }
        }
        for f: flag in c.flags {
            alt f {
              flag_left_justify. { log "flag: left justify"; }
              flag_left_zero_pad. { log "flag: left zero pad"; }
              flag_space_for_sign. { log "flag: left space pad"; }
              flag_sign_always. { log "flag: sign always"; }
              flag_alternate. { log "flag: alternate"; }
            }
        }
        alt c.width {
          count_is(i) { log "width: count is " + int::to_str(i, 10u); }
          count_is_param(i) {
            log "width: count is param " + int::to_str(i, 10u);
          }
          count_is_next_param. { log "width: count is next param"; }
          count_implied. { log "width: count is implied"; }
        }
        alt c.precision {
          count_is(i) { log "prec: count is " + int::to_str(i, 10u); }
          count_is_param(i) {
            log "prec: count is param " + int::to_str(i, 10u);
          }
          count_is_next_param. { log "prec: count is next param"; }
          count_implied. { log "prec: count is implied"; }
        }
        alt c.ty {
          ty_bool. { log "type: bool"; }
          ty_str. { log "type: str"; }
          ty_char. { log "type: char"; }
          ty_int(s) {
            alt s {
              signed. { log "type: signed"; }
              unsigned. { log "type: unsigned"; }
            }
          }
          ty_bits. { log "type: bits"; }
          ty_hex(cs) {
            alt cs {
              case_upper. { log "type: uhex"; }
              case_lower. { log "type: lhex"; }
            }
          }
          ty_octal. { log "type: octal"; }
          ty_float. { log "type: float"; }
        }
    }
    let fmt_sp = args[0].span;
    let n = 0u;
    let tmp_expr = make_new_str(cx, sp, "");
    let nargs = vec::len::<@ast::expr>(args);
    for pc: piece in pieces {
        alt pc {
          piece_string(s) {
            let s_expr = make_new_str(cx, fmt_sp, s);
            tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, s_expr);
          }
          piece_conv(conv) {
            n += 1u;
            if n >= nargs {
                cx.span_fatal(sp,
                              "not enough arguments to #fmt " +
                                  "for the given format string");
            }
            log "Building conversion:";
            log_conv(conv);
            let arg_expr = args[n];
            let c_expr = make_new_conv(cx, fmt_sp, conv, arg_expr);
            tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, c_expr);
          }
        }
    }
    let expected_nargs = n + 1u; // n conversions + the fmt string

    if expected_nargs < nargs {
        cx.span_fatal
            (sp, #fmt["too many arguments to #fmt. found %u, expected %u",
                           nargs, expected_nargs]);
    }
    ret tmp_expr;
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
<commit_msg>Switch fmt extension to reference extfmt that's in core.<commit_after>

/*
 * The compiler code necessary to support the #fmt extension. Eventually this
 * should all get sucked into either the standard library extfmt module or the
 * compiler syntax extension plugin interface.
 */
import core::{vec, str, option};
import option::{some};
import extfmt::ct::*;
import base::*;
import codemap::span;
export expand_syntax_ext;

fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: @ast::expr,
                     _body: option::t<str>) -> @ast::expr {
    let args: [@ast::expr] =
        alt arg.node {
          ast::expr_vec(elts, _) { elts }
          _ {
            cx.span_fatal(sp, "#fmt requires arguments of the form `[...]`.")
          }
        };
    if vec::len::<@ast::expr>(args) == 0u {
        cx.span_fatal(sp, "#fmt requires a format string");
    }
    let fmt =
        expr_to_str(cx, args[0],
                    "first argument to #fmt must be a " + "string literal.");
    let fmtspan = args[0].span;
    log "Format string:";
    log fmt;
    fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: str) -> ! {
        cx.span_fatal(sp, msg);
    }
    let parse_fmt_err = bind parse_fmt_err_(cx, fmtspan, _);
    let pieces = parse_fmt_string(fmt, parse_fmt_err);
    ret pieces_to_expr(cx, sp, pieces, args);
}

// FIXME: A lot of these functions for producing expressions can probably
// be factored out in common with other code that builds expressions.
// FIXME: Cleanup the naming of these functions
fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
   -> @ast::expr {
    fn make_new_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
        let sp_lit = @{node: lit, span: sp};
        ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
    }
    fn make_new_str(cx: ext_ctxt, sp: span, s: str) -> @ast::expr {
        let lit = ast::lit_str(s);
        ret make_new_lit(cx, sp, lit);
    }
    fn make_new_int(cx: ext_ctxt, sp: span, i: int) -> @ast::expr {
        let lit = ast::lit_int(i as i64, ast::ty_i);
        ret make_new_lit(cx, sp, lit);
    }
    fn make_new_uint(cx: ext_ctxt, sp: span, u: uint) -> @ast::expr {
        let lit = ast::lit_uint(u as u64, ast::ty_u);
        ret make_new_lit(cx, sp, lit);
    }
    fn make_add_expr(cx: ext_ctxt, sp: span, lhs: @ast::expr, rhs: @ast::expr)
       -> @ast::expr {
        let binexpr = ast::expr_binary(ast::add, lhs, rhs);
        ret @{id: cx.next_id(), node: binexpr, span: sp};
    }
    fn make_path_expr(cx: ext_ctxt, sp: span, idents: [ast::ident]) ->
       @ast::expr {
        let path = {global: false, idents: idents, types: []};
        let sp_path = @{node: path, span: sp};
        let pathexpr = ast::expr_path(sp_path);
        ret @{id: cx.next_id(), node: pathexpr, span: sp};
    }
    fn make_vec_expr(cx: ext_ctxt, sp: span, exprs: [@ast::expr]) ->
       @ast::expr {
        let vecexpr = ast::expr_vec(exprs, ast::imm);
        ret @{id: cx.next_id(), node: vecexpr, span: sp};
    }
    fn make_call(cx: ext_ctxt, sp: span, fn_path: [ast::ident],
                 args: [@ast::expr]) -> @ast::expr {
        let pathexpr = make_path_expr(cx, sp, fn_path);
        let callexpr = ast::expr_call(pathexpr, args, false);
        ret @{id: cx.next_id(), node: callexpr, span: sp};
    }
    fn make_rec_expr(cx: ext_ctxt, sp: span,
                     fields: [{ident: ast::ident, ex: @ast::expr}]) ->
       @ast::expr {
        let astfields: [ast::field] = [];
        for field: {ident: ast::ident, ex: @ast::expr} in fields {
            let ident = field.ident;
            let val = field.ex;
            let astfield =
                {node: {mut: ast::imm, ident: ident, expr: val}, span: sp};
            astfields += [astfield];
        }
        let recexpr = ast::expr_rec(astfields, option::none::<@ast::expr>);
        ret @{id: cx.next_id(), node: recexpr, span: sp};
    }
    fn make_path_vec(_cx: ext_ctxt, ident: ast::ident) -> [ast::ident] {
        ret ["extfmt", "rt", ident];
    }
    fn make_rt_path_expr(cx: ext_ctxt, sp: span, ident: str) -> @ast::expr {
        let path = make_path_vec(cx, ident);
        ret make_path_expr(cx, sp, path);
    }
    // Produces an AST expression that represents a RT::conv record,
    // which tells the RT::conv* functions how to perform the conversion

    fn make_rt_conv_expr(cx: ext_ctxt, sp: span, cnv: conv) -> @ast::expr {
        fn make_flags(cx: ext_ctxt, sp: span, flags: [flag]) -> @ast::expr {
            let flagexprs: [@ast::expr] = [];
            for f: flag in flags {
                let fstr;
                alt f {
                  flag_left_justify. { fstr = "flag_left_justify"; }
                  flag_left_zero_pad. { fstr = "flag_left_zero_pad"; }
                  flag_space_for_sign. { fstr = "flag_space_for_sign"; }
                  flag_sign_always. { fstr = "flag_sign_always"; }
                  flag_alternate. { fstr = "flag_alternate"; }
                }
                flagexprs += [make_rt_path_expr(cx, sp, fstr)];
            }
            // FIXME: 0-length vectors can't have their type inferred
            // through the rec that these flags are a member of, so
            // this is a hack placeholder flag

            if vec::len::<@ast::expr>(flagexprs) == 0u {
                flagexprs += [make_rt_path_expr(cx, sp, "flag_none")];
            }
            ret make_vec_expr(cx, sp, flagexprs);
        }
        fn make_count(cx: ext_ctxt, sp: span, cnt: count) -> @ast::expr {
            alt cnt {
              count_implied. {
                ret make_rt_path_expr(cx, sp, "count_implied");
              }
              count_is(c) {
                let count_lit = make_new_int(cx, sp, c);
                let count_is_path = make_path_vec(cx, "count_is");
                let count_is_args = [count_lit];
                ret make_call(cx, sp, count_is_path, count_is_args);
              }
              _ { cx.span_unimpl(sp, "unimplemented #fmt conversion"); }
            }
        }
        fn make_ty(cx: ext_ctxt, sp: span, t: ty) -> @ast::expr {
            let rt_type;
            alt t {
              ty_hex(c) {
                alt c {
                  case_upper. { rt_type = "ty_hex_upper"; }
                  case_lower. { rt_type = "ty_hex_lower"; }
                }
              }
              ty_bits. { rt_type = "ty_bits"; }
              ty_octal. { rt_type = "ty_octal"; }
              _ { rt_type = "ty_default"; }
            }
            ret make_rt_path_expr(cx, sp, rt_type);
        }
        fn make_conv_rec(cx: ext_ctxt, sp: span, flags_expr: @ast::expr,
                         width_expr: @ast::expr, precision_expr: @ast::expr,
                         ty_expr: @ast::expr) -> @ast::expr {
            ret make_rec_expr(cx, sp,
                              [{ident: "flags", ex: flags_expr},
                               {ident: "width", ex: width_expr},
                               {ident: "precision", ex: precision_expr},
                               {ident: "ty", ex: ty_expr}]);
        }
        let rt_conv_flags = make_flags(cx, sp, cnv.flags);
        let rt_conv_width = make_count(cx, sp, cnv.width);
        let rt_conv_precision = make_count(cx, sp, cnv.precision);
        let rt_conv_ty = make_ty(cx, sp, cnv.ty);
        ret make_conv_rec(cx, sp, rt_conv_flags, rt_conv_width,
                          rt_conv_precision, rt_conv_ty);
    }
    fn make_conv_call(cx: ext_ctxt, sp: span, conv_type: str, cnv: conv,
                      arg: @ast::expr) -> @ast::expr {
        let fname = "conv_" + conv_type;
        let path = make_path_vec(cx, fname);
        let cnv_expr = make_rt_conv_expr(cx, sp, cnv);
        let args = [cnv_expr, arg];
        ret make_call(cx, arg.span, path, args);
    }
    fn make_new_conv(cx: ext_ctxt, sp: span, cnv: conv, arg: @ast::expr) ->
       @ast::expr {
        // FIXME: Extract all this validation into extfmt::ct

        fn is_signed_type(cnv: conv) -> bool {
            alt cnv.ty {
              ty_int(s) {
                alt s { signed. { ret true; } unsigned. { ret false; } }
              }
              ty_float. { ret true; }
              _ { ret false; }
            }
        }
        let unsupported = "conversion not supported in #fmt string";
        alt cnv.param {
          option::none. { }
          _ { cx.span_unimpl(sp, unsupported); }
        }
        for f: flag in cnv.flags {
            alt f {
              flag_left_justify. { }
              flag_sign_always. {
                if !is_signed_type(cnv) {
                    cx.span_fatal(sp,
                                  "+ flag only valid in " +
                                      "signed #fmt conversion");
                }
              }
              flag_space_for_sign. {
                if !is_signed_type(cnv) {
                    cx.span_fatal(sp,
                                  "space flag only valid in " +
                                      "signed #fmt conversions");
                }
              }
              flag_left_zero_pad. { }
              _ { cx.span_unimpl(sp, unsupported); }
            }
        }
        alt cnv.width {
          count_implied. { }
          count_is(_) { }
          _ { cx.span_unimpl(sp, unsupported); }
        }
        alt cnv.precision {
          count_implied. { }
          count_is(_) { }
          _ { cx.span_unimpl(sp, unsupported); }
        }
        alt cnv.ty {
          ty_str. { ret make_conv_call(cx, arg.span, "str", cnv, arg); }
          ty_int(sign) {
            alt sign {
              signed. { ret make_conv_call(cx, arg.span, "int", cnv, arg); }
              unsigned. {
                ret make_conv_call(cx, arg.span, "uint", cnv, arg);
              }
            }
          }
          ty_bool. { ret make_conv_call(cx, arg.span, "bool", cnv, arg); }
          ty_char. { ret make_conv_call(cx, arg.span, "char", cnv, arg); }
          ty_hex(_) { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
          ty_bits. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
          ty_octal. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
          ty_float. { ret make_conv_call(cx, arg.span, "float", cnv, arg); }
          _ { cx.span_unimpl(sp, unsupported); }
        }
    }
    fn log_conv(c: conv) {
        alt c.param {
          some(p) { log "param: " + int::to_str(p, 10u); }
          _ { log "param: none"; }
        }
        for f: flag in c.flags {
            alt f {
              flag_left_justify. { log "flag: left justify"; }
              flag_left_zero_pad. { log "flag: left zero pad"; }
              flag_space_for_sign. { log "flag: left space pad"; }
              flag_sign_always. { log "flag: sign always"; }
              flag_alternate. { log "flag: alternate"; }
            }
        }
        alt c.width {
          count_is(i) { log "width: count is " + int::to_str(i, 10u); }
          count_is_param(i) {
            log "width: count is param " + int::to_str(i, 10u);
          }
          count_is_next_param. { log "width: count is next param"; }
          count_implied. { log "width: count is implied"; }
        }
        alt c.precision {
          count_is(i) { log "prec: count is " + int::to_str(i, 10u); }
          count_is_param(i) {
            log "prec: count is param " + int::to_str(i, 10u);
          }
          count_is_next_param. { log "prec: count is next param"; }
          count_implied. { log "prec: count is implied"; }
        }
        alt c.ty {
          ty_bool. { log "type: bool"; }
          ty_str. { log "type: str"; }
          ty_char. { log "type: char"; }
          ty_int(s) {
            alt s {
              signed. { log "type: signed"; }
              unsigned. { log "type: unsigned"; }
            }
          }
          ty_bits. { log "type: bits"; }
          ty_hex(cs) {
            alt cs {
              case_upper. { log "type: uhex"; }
              case_lower. { log "type: lhex"; }
            }
          }
          ty_octal. { log "type: octal"; }
          ty_float. { log "type: float"; }
        }
    }
    let fmt_sp = args[0].span;
    let n = 0u;
    let tmp_expr = make_new_str(cx, sp, "");
    let nargs = vec::len::<@ast::expr>(args);
    for pc: piece in pieces {
        alt pc {
          piece_string(s) {
            let s_expr = make_new_str(cx, fmt_sp, s);
            tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, s_expr);
          }
          piece_conv(conv) {
            n += 1u;
            if n >= nargs {
                cx.span_fatal(sp,
                              "not enough arguments to #fmt " +
                                  "for the given format string");
            }
            log "Building conversion:";
            log_conv(conv);
            let arg_expr = args[n];
            let c_expr = make_new_conv(cx, fmt_sp, conv, arg_expr);
            tmp_expr = make_add_expr(cx, fmt_sp, tmp_expr, c_expr);
          }
        }
    }
    let expected_nargs = n + 1u; // n conversions + the fmt string

    if expected_nargs < nargs {
        cx.span_fatal
            (sp, #fmt["too many arguments to #fmt. found %u, expected %u",
                           nargs, expected_nargs]);
    }
    ret tmp_expr;
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//
<|endoftext|>


<commit_before>use {Field, Value, Borrowed, Matrix2d, Color};
use vecmath::{multiply, translate, rotate_radians, scale, shear, identity};
use {Transform2d, Fill, BackEnd, Clear, View};
use triangulation::{
    with_polygon_tri_list_xy_f32_rgba_f32
};

/// A polygon color context.
pub struct PolygonColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Current polygon.
    pub polygon: Field<'a, &'a [f64]>,
}

impl<'a> Transform2d<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn trans_local(&'a self, x: f64, y: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(self.transform.get(), &trans))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad_local(&'a self, angle: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(self.transform.get(), &rot))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale_local(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(self.transform.get(), &scale))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear_local(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(self.transform.get(), &shear))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> Fill<'a> for PolygonColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let polygon = self.polygon.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_polygon_tri_list_xy_f32_rgba_f32(
                self.transform.get(),
                *polygon,
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> Clear for PolygonColorContext<'a> {
    fn clear<B: BackEnd>(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        } else {
            unimplemented!();
        }
    }
}

impl<'a> View<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

<commit_msg>Sorted use alphabetically<commit_after>use {
    BackEnd,
    Borrowed,
    Clear,
    Color,
    Field,
    Fill,
    Matrix2d,
    Value,
    View,
    Transform2d,
};
use vecmath::{
    identity,
    multiply,
    rotate_radians,
    scale,
    shear,
    translate,
};
use triangulation::{
    with_polygon_tri_list_xy_f32_rgba_f32
};

/// A polygon color context.
pub struct PolygonColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Current polygon.
    pub polygon: Field<'a, &'a [f64]>,
}

impl<'a> Transform2d<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn trans_local(&'a self, x: f64, y: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(self.transform.get(), &trans))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad_local(&'a self, angle: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(self.transform.get(), &rot))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale_local(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(self.transform.get(), &scale))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear_local(&'a self, sx: f64, sy: f64) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(self.transform.get(), &shear))
            },
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> Fill<'a> for PolygonColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let polygon = self.polygon.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_polygon_tri_list_xy_f32_rgba_f32(
                self.transform.get(),
                *polygon,
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> Clear for PolygonColorContext<'a> {
    fn clear<B: BackEnd>(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        } else {
            unimplemented!();
        }
    }
}

impl<'a> View<'a> for PolygonColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> PolygonColorContext<'a> {
        PolygonColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            polygon: Borrowed(self.polygon.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

<|endoftext|>


<commit_before>// Tuples can be used as function arguments and as return values
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    // `let` can be used to bind the members of a tuple to variables
    let (integer, boolean) = pair;

    (boolean, integer)
}

// The following struct is for the activity.
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

pub fn main() {
    // A tuple with a bunch of different types
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Values can be extracted from the tuple using tuple indexing
    println!("long tuple first value: {}", long_tuple.0);
    println!("long tuple second value: {}", long_tuple.1);

    // Tuples can be tuple members
    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

    // Tuples are printable
    println!("tuple of tuples: {:?}", tuple_of_tuples);

    let pair = (1, true);
    println!("pair is {:?}", pair);

    println!("the reversed pair is {:?}", reverse(pair));

    // To create one element tuples, the comma is required to tell them apart
    // from a literal surrounded by parentheses
    println!("one element tuple: {:?}", (5u32,));
    println!("just an integer: {:?}", (5u32));

    //tuples can be destructured to create bindings
    let tuple = (1, "hello", 4.5, true);

    let (a, b, c, d) = tuple;
    println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d);

    let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
    println!("{:?}", matrix)
}<commit_msg>Rust By Examples [RBE] - 2.2 Tuples - Activity: Display trait<commit_after>use std::fmt;

// Tuples can be used as function arguments and as return values
fn reverse(pair: (i32, bool)) -> (bool, i32) {
    // `let` can be used to bind the members of a tuple to variables
    let (integer, boolean) = pair;

    (boolean, integer)
}

// The following struct is for the activity.
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);

impl fmt::Display for Matrix {
    // This trait requires `fmt` with this exact signature.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "( {}, {}, {}, {} )", self.0, self.1, self.2, self.3)
    }
}

pub fn main() {
    // A tuple with a bunch of different types
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Values can be extracted from the tuple using tuple indexing
    println!("long tuple first value: {}", long_tuple.0);
    println!("long tuple second value: {}", long_tuple.1);

    // Tuples can be tuple members
    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

    // Tuples are printable
    println!("tuple of tuples: {:?}", tuple_of_tuples);

    let pair = (1, true);
    println!("pair is {:?}", pair);

    println!("the reversed pair is {:?}", reverse(pair));

    // To create one element tuples, the comma is required to tell them apart
    // from a literal surrounded by parentheses
    println!("one element tuple: {:?}", (5u32,));
    println!("just an integer: {:?}", (5u32));

    //tuples can be destructured to create bindings
    let tuple = (1, "hello", 4.5, true);

    let (a, b, c, d) = tuple;
    println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d);

    let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
    println!("{:?}", matrix);
    println!("{}", matrix);
}<|endoftext|>