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

//! MSVC-specific logic for linkers and such.
//!
//! This module contains a cross-platform interface but has a blank unix
//! implementation. The Windows implementation builds on top of Windows native
//! libraries (reading registry keys), so it otherwise wouldn't link on unix.
//!
//! Note that we don't have much special logic for finding the system linker on
//! any other platforms, so it may seem a little odd to single out MSVC to have
//! a good deal of code just to find the linker. Unlike Unix systems, however,
//! the MSVC linker is not in the system PATH by default. It also additionally
//! needs a few environment variables or command line flags to be able to link
//! against system libraries.
//!
//! In order to have a nice smooth experience on Windows, the logic in this file
//! is here to find the MSVC linker and set it up in the default configuration
//! one would need to set up anyway. This means that the Rust compiler can be
//! run not only in the developer shells of MSVC but also the standard cmd.exe
//! shell or MSYS shells.
//!
//! As a high-level note, all logic in this module for looking up various
//! paths/files is based on Microsoft's logic in their vcvars bat files, but
//! comments can also be found below leading through the various code paths.

use std::process::Command;
use session::Session;

#[cfg(windows)]
mod registry;

#[cfg(windows)]
pub fn link_exe_cmd(sess: &Session) -> Command {
    use std::env;
    use std::ffi::OsString;
    use std::fs;
    use std::path::{Path, PathBuf};
    use self::registry::{LOCAL_MACHINE};

    let arch = &sess.target.target.arch;
    let (binsub, libsub, vclibsub) =
        match (bin_subdir(arch), lib_subdir(arch), vc_lib_subdir(arch)) {
        (Some(x), Some(y), Some(z)) => (x, y, z),
        _ => return Command::new("link.exe"),
    };

    // First we need to figure out whether the environment is already correctly
    // configured by vcvars. We do this by looking at the environment variable
    // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set
    // otherwise. If it is defined, then we derive the path to `link.exe` from
    // that and trust that everything else is configured correctly.
    //
    // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where it
    // claimed it should be), then we resort to finding everything ourselves.
    // First we find where the latest version of MSVC is installed and what
    // version it is. Then based on the version we find the appropriate SDKs.
    //
    // For MSVC 14 (VS 2015) we look for the Win10 SDK and failing that we look
    // for the Win8.1 SDK. We also look for the Universal CRT.
    //
    // For MSVC 12 (VS 2013) we look for the Win8.1 SDK.
    //
    // For MSVC 11 (VS 2012) we look for the Win8 SDK.
    //
    // For all other versions the user has to execute the appropriate vcvars bat
    // file themselves to configure the environment.
    //
    // If despite our best efforts we are still unable to find MSVC then we just
    // blindly call `link.exe` and hope for the best.
    return env::var_os("VCINSTALLDIR").and_then(|dir| {
        debug!("Environment already configured by user. Assuming it works.");
        let mut p = PathBuf::from(dir);
        p.push("bin");
        p.push(binsub);
        p.push("link.exe");
        if !p.is_file() { return None }
        Some(Command::new(p))
    }).or_else(|| {
        get_vc_dir().and_then(|(ver, vcdir)| {
            debug!("Found VC installation directory {:?}", vcdir);
            let mut linker = vcdir.clone();
            linker.push("bin");
            linker.push(binsub);
            linker.push("link.exe");
            if !linker.is_file() { return None }
            let mut cmd = Command::new(linker);
            add_lib(&mut cmd, &vcdir.join("lib").join(vclibsub));
            if ver == "14.0" {
                if let Some(dir) = get_ucrt_dir() {
                    debug!("Found Universal CRT {:?}", dir);
                    add_lib(&mut cmd, &dir.join("ucrt").join(libsub));
                }
                if let Some(dir) = get_sdk10_dir() {
                    debug!("Found Win10 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                } else if let Some(dir) = get_sdk81_dir() {
                    debug!("Found Win8.1 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                }
            } else if ver == "12.0" {
                if let Some(dir) = get_sdk81_dir() {
                    debug!("Found Win8.1 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                }
            } else { // ver == "11.0"
                if let Some(dir) = get_sdk8_dir() {
                    debug!("Found Win8 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                }
            }
            Some(cmd)
        })
    }).unwrap_or_else(|| {
        debug!("Failed to locate linker.");
        Command::new("link.exe")
    });

    // A convenience function to make the above code simpler
    fn add_lib(cmd: &mut Command, lib: &Path) {
        let mut arg: OsString = "/LIBPATH:".into();
        arg.push(lib);
        cmd.arg(arg);
    }

    // To find MSVC we look in a specific registry key for the newest of the
    // three versions that we support.
    fn get_vc_dir() -> Option<(&'static str, PathBuf)> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7".as_ref())
        .ok().and_then(|key| {
            ["14.0", "12.0", "11.0"].iter().filter_map(|ver| {
                key.query_str(ver).ok().map(|p| (*ver, p.into()))
            }).next()
        })
    }

    // To find the Universal CRT we look in a specific registry key for where
    // all the Universal CRTs are located and then sort them asciibetically to
    // find the newest version. While this sort of sorting isn't ideal,  it is
    // what vcvars does so that's good enough for us.
    fn get_ucrt_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots".as_ref())
        .ok().and_then(|key| {
            key.query_str("KitsRoot10").ok()
        }).and_then(|root| {
            fs::read_dir(Path::new(&root).join("Lib")).ok()
        }).and_then(|readdir| {
            let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok())
                .map(|dir| dir.path()).collect();
            dirs.sort();
            dirs.pop()
        })
    }

    // Vcvars finds the correct version of the Windows 10 SDK by looking
    // for the include um/Windows.h because sometimes a given version will
    // only have UCRT bits without the rest of the SDK. Since we only care about
    // libraries and not includes, we just look for the folder `um` in the lib
    // section. Like we do for the Universal CRT, we sort the possibilities
    // asciibetically to find the newest one as that is what vcvars does.
    fn get_sdk10_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0".as_ref())
        .ok().and_then(|key| {
            key.query_str("InstallationFolder").ok()
        }).and_then(|root| {
            fs::read_dir(Path::new(&root).join("lib")).ok()
        }).and_then(|readdir| {
            let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok())
                .map(|dir| dir.path()).collect();
            dirs.sort();
            dirs.into_iter().rev().filter(|dir| {
                dir.join("um").is_dir()
            }).next()
        })
    }

    // Interestingly there are several subdirectories, `win7` `win8` and
    // `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same
    // applies to us. Note that if we were targetting kernel mode drivers
    // instead of user mode applications, we would care.
    fn get_sdk81_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1".as_ref())
        .ok().and_then(|key| {
            key.query_str("InstallationFolder").ok()
        }).map(|root| {
            Path::new(&root).join("lib").join("winv6.3")
        })
    }

    fn get_sdk8_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0".as_ref())
        .ok().and_then(|key| {
            key.query_str("InstallationFolder").ok()
        }).map(|root| {
            Path::new(&root).join("lib").join("win8")
        })
    }

    // When choosing the linker toolchain to use, we have to choose the one
    // which matches the host architecture. Otherwise we end up in situations
    // where someone on 32-bit Windows is trying to cross compile to 64-bit and
    // it tries to invoke the native 64-bit linker which won't work.
    //
    // FIXME - This currently functions based on the host architecture of rustc
    // itself but it should instead detect the bitness of the OS itself.
    //
    // FIXME - Figure out what happens when the host architecture is arm.
    //
    // FIXME - Some versions of MSVC may not come with all these toolchains.
    // Consider returning an array of toolchains and trying them one at a time
    // until the linker is found.
    fn bin_subdir(arch: &str) -> Option<&'static str> {
        if cfg!(target_arch = "x86_64") {
            match arch {
                "x86" => Some("amd64_x86"),
                "x86_64" => Some("amd64"),
                "arm" => Some("amd64_arm"),
                _ => None,
            }
        } else if cfg!(target_arch = "x86") {
            match arch {
                "x86" => Some(""),
                "x86_64" => Some("x86_amd64"),
                "arm" => Some("x86_arm"),
                _ => None,
            }
        } else { None }
    }
    fn lib_subdir(arch: &str) -> Option<&'static str> {
        match arch {
            "x86" => Some("x86"),
            "x86_64" => Some("x64"),
            "arm" => Some("arm"),
            _ => None,
        }
    }
    // MSVC's x86 libraries are not in a subfolder
    fn vc_lib_subdir(arch: &str) -> Option<&'static str> {
        match arch {
            "x86" => Some(""),
            "x86_64" => Some("amd64"),
            "arm" => Some("arm"),
            _ => None,
        }
    }
}

// If we're not on Windows, then there's no registry to search through and MSVC
// wouldn't be able to run, so we just call `link.exe` and hope for the best.
#[cfg(not(windows))]
pub fn link_exe_cmd(_sess: &Session) -> Command {
    Command::new("link.exe")
}
<commit_msg>Fix Universal CRT detection on weird setups Checks for a `10.` prefix on the subfolder<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! MSVC-specific logic for linkers and such.
//!
//! This module contains a cross-platform interface but has a blank unix
//! implementation. The Windows implementation builds on top of Windows native
//! libraries (reading registry keys), so it otherwise wouldn't link on unix.
//!
//! Note that we don't have much special logic for finding the system linker on
//! any other platforms, so it may seem a little odd to single out MSVC to have
//! a good deal of code just to find the linker. Unlike Unix systems, however,
//! the MSVC linker is not in the system PATH by default. It also additionally
//! needs a few environment variables or command line flags to be able to link
//! against system libraries.
//!
//! In order to have a nice smooth experience on Windows, the logic in this file
//! is here to find the MSVC linker and set it up in the default configuration
//! one would need to set up anyway. This means that the Rust compiler can be
//! run not only in the developer shells of MSVC but also the standard cmd.exe
//! shell or MSYS shells.
//!
//! As a high-level note, all logic in this module for looking up various
//! paths/files is based on Microsoft's logic in their vcvars bat files, but
//! comments can also be found below leading through the various code paths.

use std::process::Command;
use session::Session;

#[cfg(windows)]
mod registry;

#[cfg(windows)]
pub fn link_exe_cmd(sess: &Session) -> Command {
    use std::env;
    use std::ffi::OsString;
    use std::fs;
    use std::path::{Path, PathBuf};
    use self::registry::{LOCAL_MACHINE};

    let arch = &sess.target.target.arch;
    let (binsub, libsub, vclibsub) =
        match (bin_subdir(arch), lib_subdir(arch), vc_lib_subdir(arch)) {
        (Some(x), Some(y), Some(z)) => (x, y, z),
        _ => return Command::new("link.exe"),
    };

    // First we need to figure out whether the environment is already correctly
    // configured by vcvars. We do this by looking at the environment variable
    // `VCINSTALLDIR` which is always set by vcvars, and unlikely to be set
    // otherwise. If it is defined, then we derive the path to `link.exe` from
    // that and trust that everything else is configured correctly.
    //
    // If `VCINSTALLDIR` wasn't defined (or we couldn't find the linker where it
    // claimed it should be), then we resort to finding everything ourselves.
    // First we find where the latest version of MSVC is installed and what
    // version it is. Then based on the version we find the appropriate SDKs.
    //
    // For MSVC 14 (VS 2015) we look for the Win10 SDK and failing that we look
    // for the Win8.1 SDK. We also look for the Universal CRT.
    //
    // For MSVC 12 (VS 2013) we look for the Win8.1 SDK.
    //
    // For MSVC 11 (VS 2012) we look for the Win8 SDK.
    //
    // For all other versions the user has to execute the appropriate vcvars bat
    // file themselves to configure the environment.
    //
    // If despite our best efforts we are still unable to find MSVC then we just
    // blindly call `link.exe` and hope for the best.
    return env::var_os("VCINSTALLDIR").and_then(|dir| {
        debug!("Environment already configured by user. Assuming it works.");
        let mut p = PathBuf::from(dir);
        p.push("bin");
        p.push(binsub);
        p.push("link.exe");
        if !p.is_file() { return None }
        Some(Command::new(p))
    }).or_else(|| {
        get_vc_dir().and_then(|(ver, vcdir)| {
            debug!("Found VC installation directory {:?}", vcdir);
            let mut linker = vcdir.clone();
            linker.push("bin");
            linker.push(binsub);
            linker.push("link.exe");
            if !linker.is_file() { return None }
            let mut cmd = Command::new(linker);
            add_lib(&mut cmd, &vcdir.join("lib").join(vclibsub));
            if ver == "14.0" {
                if let Some(dir) = get_ucrt_dir() {
                    debug!("Found Universal CRT {:?}", dir);
                    add_lib(&mut cmd, &dir.join("ucrt").join(libsub));
                }
                if let Some(dir) = get_sdk10_dir() {
                    debug!("Found Win10 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                } else if let Some(dir) = get_sdk81_dir() {
                    debug!("Found Win8.1 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                }
            } else if ver == "12.0" {
                if let Some(dir) = get_sdk81_dir() {
                    debug!("Found Win8.1 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                }
            } else { // ver == "11.0"
                if let Some(dir) = get_sdk8_dir() {
                    debug!("Found Win8 SDK {:?}", dir);
                    add_lib(&mut cmd, &dir.join("um").join(libsub));
                }
            }
            Some(cmd)
        })
    }).unwrap_or_else(|| {
        debug!("Failed to locate linker.");
        Command::new("link.exe")
    });

    // A convenience function to make the above code simpler
    fn add_lib(cmd: &mut Command, lib: &Path) {
        let mut arg: OsString = "/LIBPATH:".into();
        arg.push(lib);
        cmd.arg(arg);
    }

    // To find MSVC we look in a specific registry key for the newest of the
    // three versions that we support.
    fn get_vc_dir() -> Option<(&'static str, PathBuf)> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7".as_ref())
        .ok().and_then(|key| {
            ["14.0", "12.0", "11.0"].iter().filter_map(|ver| {
                key.query_str(ver).ok().map(|p| (*ver, p.into()))
            }).next()
        })
    }

    // To find the Universal CRT we look in a specific registry key for where
    // all the Universal CRTs are located and then sort them asciibetically to
    // find the newest version. While this sort of sorting isn't ideal,  it is
    // what vcvars does so that's good enough for us.
    fn get_ucrt_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots".as_ref())
        .ok().and_then(|key| {
            key.query_str("KitsRoot10").ok()
        }).and_then(|root| {
            fs::read_dir(Path::new(&root).join("Lib")).ok()
        }).and_then(|readdir| {
            let mut dirs: Vec<_> = readdir.filter_map(|dir| {
                dir.ok()
            }).map(|dir| {
                dir.path()
            }).filter(|dir| {
                dir.components().last().and_then(|c| {
                    c.as_os_str().to_str()
                }).map(|c| c.starts_with("10.")).unwrap_or(false)
            }).collect();
            dirs.sort();
            dirs.pop()
        })
    }

    // Vcvars finds the correct version of the Windows 10 SDK by looking
    // for the include um/Windows.h because sometimes a given version will
    // only have UCRT bits without the rest of the SDK. Since we only care about
    // libraries and not includes, we just look for the folder `um` in the lib
    // section. Like we do for the Universal CRT, we sort the possibilities
    // asciibetically to find the newest one as that is what vcvars does.
    fn get_sdk10_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0".as_ref())
        .ok().and_then(|key| {
            key.query_str("InstallationFolder").ok()
        }).and_then(|root| {
            fs::read_dir(Path::new(&root).join("lib")).ok()
        }).and_then(|readdir| {
            let mut dirs: Vec<_> = readdir.filter_map(|dir| dir.ok())
                .map(|dir| dir.path()).collect();
            dirs.sort();
            dirs.into_iter().rev().filter(|dir| {
                dir.join("um").is_dir()
            }).next()
        })
    }

    // Interestingly there are several subdirectories, `win7` `win8` and
    // `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same
    // applies to us. Note that if we were targetting kernel mode drivers
    // instead of user mode applications, we would care.
    fn get_sdk81_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1".as_ref())
        .ok().and_then(|key| {
            key.query_str("InstallationFolder").ok()
        }).map(|root| {
            Path::new(&root).join("lib").join("winv6.3")
        })
    }

    fn get_sdk8_dir() -> Option<PathBuf> {
        LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0".as_ref())
        .ok().and_then(|key| {
            key.query_str("InstallationFolder").ok()
        }).map(|root| {
            Path::new(&root).join("lib").join("win8")
        })
    }

    // When choosing the linker toolchain to use, we have to choose the one
    // which matches the host architecture. Otherwise we end up in situations
    // where someone on 32-bit Windows is trying to cross compile to 64-bit and
    // it tries to invoke the native 64-bit linker which won't work.
    //
    // FIXME - This currently functions based on the host architecture of rustc
    // itself but it should instead detect the bitness of the OS itself.
    //
    // FIXME - Figure out what happens when the host architecture is arm.
    //
    // FIXME - Some versions of MSVC may not come with all these toolchains.
    // Consider returning an array of toolchains and trying them one at a time
    // until the linker is found.
    fn bin_subdir(arch: &str) -> Option<&'static str> {
        if cfg!(target_arch = "x86_64") {
            match arch {
                "x86" => Some("amd64_x86"),
                "x86_64" => Some("amd64"),
                "arm" => Some("amd64_arm"),
                _ => None,
            }
        } else if cfg!(target_arch = "x86") {
            match arch {
                "x86" => Some(""),
                "x86_64" => Some("x86_amd64"),
                "arm" => Some("x86_arm"),
                _ => None,
            }
        } else { None }
    }
    fn lib_subdir(arch: &str) -> Option<&'static str> {
        match arch {
            "x86" => Some("x86"),
            "x86_64" => Some("x64"),
            "arm" => Some("arm"),
            _ => None,
        }
    }
    // MSVC's x86 libraries are not in a subfolder
    fn vc_lib_subdir(arch: &str) -> Option<&'static str> {
        match arch {
            "x86" => Some(""),
            "x86_64" => Some("amd64"),
            "arm" => Some("arm"),
            _ => None,
        }
    }
}

// If we're not on Windows, then there's no registry to search through and MSVC
// wouldn't be able to run, so we just call `link.exe` and hope for the best.
#[cfg(not(windows))]
pub fn link_exe_cmd(_sess: &Session) -> Command {
    Command::new("link.exe")
}
<|endoftext|>


<commit_before><commit_msg>Add support for vars in daemon<commit_after><|endoftext|>


<commit_before><commit_msg>finish rust version<commit_after>#[derive(Debug)]
struct ListNode {
    Val: i32,
    Next: Option<Box<ListNode>>,
}

impl ListNode {
    fn new(input: Vec<i32>) -> Self {
        let mut result = ListNode {
            Val: input[0],
            Next: None,
        };
        {
            let mut p_result = &mut result;
            for i in input.into_iter().skip(1) {
                p_result.Next = Some(Box::new(ListNode { Val: i, Next: None }));
                p_result = { p_result }.Next.as_mut().unwrap();
            }
        }
        result
    }

    fn middle_node(&self) -> &Self {
        let mut temp0 = self;
        let mut temp1 = if let Some(ref a) = self.Next {
            a
        } else {
            return temp0;
        };

        loop {
            if let None = temp1.Next {
                return temp0.Next.as_ref().unwrap();
            }
            match temp1.Next.as_ref().unwrap().Next {
                Some(_) => {}
                None => return temp0.Next.as_ref().unwrap(),
            }

            temp0 = &temp0.Next.as_ref().unwrap();
            temp1 = &temp1.Next.as_ref().unwrap().Next.as_ref().unwrap();
        }
    }
}

fn main() {
    let a = ListNode::new(vec![1, 2, 3, 4, 5]);
    let b = ListNode::new(vec![1, 2, 3, 4, 5, 6]);
    let c = ListNode::new(vec![1]);

    println!("{:#?}", a.middle_node());
    println!("{:#?}", b.middle_node());
    println!("{:#?}", c.middle_node());
}
<|endoftext|>


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

fn foopy() {}

const f: fn() = foopy; //~ ERROR mismatched types: expected `&static/fn()`

fn main () {
    f();
}<|endoftext|>


<commit_before><commit_msg>I think I finished #3?<commit_after><|endoftext|>


<commit_before>//! Code for applying CSS styles to the DOM.
//!
//! This is not very interesting at the moment.  It will get much more
//! complicated if I add support for compound selectors.

use dom::{Node, Element, ElementData};
use css::{Stylesheet, Rule, Selector, Simple, SimpleSelector, Value, Keyword};
use std::collections::hashmap::HashMap;

/// Map from CSS property names to values.
pub type PropertyMap =  HashMap<String, Value>;

/// A node with associated style data.
pub struct StyledNode<'a> {
    pub node: &'a Node,
    pub specified_values: PropertyMap,
    pub children: Vec<StyledNode<'a>>,
}

#[deriving(PartialEq)]
pub enum Display {
    Inline,
    Block,
    None,
}

impl<'a> StyledNode<'a> {
    pub fn value(&self, name: &str) -> Option<Value> {
        self.specified_values.find_equiv(&name).map(|v| v.clone())
    }

    pub fn lookup(&self, name: &str, fallback_name: &str, default: &Value) -> Value {
        self.value(name).unwrap_or_else(|| self.value(fallback_name).unwrap_or_else(|| default.clone()))
    }

    pub fn display(&self) -> Display {
        match self.value("display") {
            Some(Keyword(s)) => match s.as_slice() {
                "inline" => Inline,
                "none" => None,
                _ => Block
            },
            _ => Block
        }
    }
}

/// Apply a stylesheet to an entire DOM tree, returning a StyledNode tree.
///
/// This finds only the specified values at the moment. Eventually it should be extended to find the
/// computed values too, including inherited values.
pub fn style_tree<'a>(root: &'a Node, stylesheet: &'a Stylesheet) -> StyledNode<'a> {
    StyledNode {
        node: root,
        specified_values: match root.node_type {
            Element(ref elem) => specified_values(elem, stylesheet),
            _ => HashMap::new(),
        },
        children: root.children.iter().map(|child| style_tree(child, stylesheet)).collect(),
    }
}

/// Apply styles to a single element, returning the specified styles.
///
/// To do: Allow multiple UA/author/user stylesheets, and implement the cascade.
fn specified_values(elem: &ElementData, stylesheet: &Stylesheet) -> PropertyMap {
    let mut values = HashMap::new();
    let mut rules = matching_rules(elem, stylesheet);

    // Go through the rules from lowest to highest specificity.
    rules.sort_by(|&(a, _), &(b, _)| a.specificity().cmp(&b.specificity()));
    for &(_, rule) in rules.iter() {
        for declaration in rule.declarations.iter() {
            values.insert(declaration.name.clone(), declaration.value.clone());
        }
    }
    values
}

/// A single CSS rule and the highest-specificity selector that resulted in a given match.
type MatchedRule<'a> = (&'a Selector, &'a Rule);

/// Find all CSS rules that match the given element.
fn matching_rules<'a>(elem: &ElementData, stylesheet: &'a Stylesheet) -> Vec<MatchedRule<'a>> {
    // For now, we just do a linear scan of all the rules.  For large
    // documents, it would be more efficient to store the rules in hash tables
    // based on tag name, id, class, etc.
    stylesheet.rules.iter()
        .filter_map(|rule| {
            // Find the first (highest-specificity) matching selector.
            rule.selectors.iter().find(|selector| matches(elem, *selector))
                .map(|selector| (selector, rule))
        }).collect()
}

/// Selector matching:
fn matches(elem: &ElementData, selector: &Selector) -> bool {
    match *selector {
        Simple(ref simple_selector) => matches_simple_selector(elem, simple_selector)
    }
}

fn matches_simple_selector(elem: &ElementData, selector: &SimpleSelector) -> bool {
    // Check type selector
    if selector.tag_name.iter().any(|name| elem.tag_name != *name) {
        return false;
    }

    // Check ID selector
    if selector.id.iter().any(|id| {
        elem.id().iter().any(|elem_id| {
            *elem_id != id
    })}) {
        return false;
    }

    // Check class selectors
    let elem_classes = elem.classes();
    if selector.class.iter().any(|class| !elem_classes.contains(&class.as_slice())) {
        return false;
    }

    // We didn't find any non-matching selector components.
    return true;
}
<commit_msg>Add comments to StyledNode methods<commit_after>//! Code for applying CSS styles to the DOM.
//!
//! This is not very interesting at the moment.  It will get much more
//! complicated if I add support for compound selectors.

use dom::{Node, Element, ElementData};
use css::{Stylesheet, Rule, Selector, Simple, SimpleSelector, Value, Keyword};
use std::collections::hashmap::HashMap;

/// Map from CSS property names to values.
pub type PropertyMap =  HashMap<String, Value>;

/// A node with associated style data.
pub struct StyledNode<'a> {
    pub node: &'a Node,
    pub specified_values: PropertyMap,
    pub children: Vec<StyledNode<'a>>,
}

#[deriving(PartialEq)]
pub enum Display {
    Inline,
    Block,
    None,
}

impl<'a> StyledNode<'a> {
    /// Return the specified value of a property if it exists, otherwise `None`.
    pub fn value(&self, name: &str) -> Option<Value> {
        self.specified_values.find_equiv(&name).map(|v| v.clone())
    }

    /// Return the specified value of property `name`, or property `fallback_name` if that doesn't
    /// exist. or value `default` if neither does.
    pub fn lookup(&self, name: &str, fallback_name: &str, default: &Value) -> Value {
        self.value(name).unwrap_or_else(|| self.value(fallback_name)
                        .unwrap_or_else(|| default.clone()))
    }

    /// The value of the `display` property (defaults to `Block`).
    pub fn display(&self) -> Display {
        match self.value("display") {
            Some(Keyword(s)) => match s.as_slice() {
                "inline" => Inline,
                "none" => None,
                _ => Block
            },
            _ => Block
        }
    }
}

/// Apply a stylesheet to an entire DOM tree, returning a StyledNode tree.
///
/// This finds only the specified values at the moment. Eventually it should be extended to find the
/// computed values too, including inherited values.
pub fn style_tree<'a>(root: &'a Node, stylesheet: &'a Stylesheet) -> StyledNode<'a> {
    StyledNode {
        node: root,
        specified_values: match root.node_type {
            Element(ref elem) => specified_values(elem, stylesheet),
            _ => HashMap::new(),
        },
        children: root.children.iter().map(|child| style_tree(child, stylesheet)).collect(),
    }
}

/// Apply styles to a single element, returning the specified styles.
///
/// To do: Allow multiple UA/author/user stylesheets, and implement the cascade.
fn specified_values(elem: &ElementData, stylesheet: &Stylesheet) -> PropertyMap {
    let mut values = HashMap::new();
    let mut rules = matching_rules(elem, stylesheet);

    // Go through the rules from lowest to highest specificity.
    rules.sort_by(|&(a, _), &(b, _)| a.specificity().cmp(&b.specificity()));
    for &(_, rule) in rules.iter() {
        for declaration in rule.declarations.iter() {
            values.insert(declaration.name.clone(), declaration.value.clone());
        }
    }
    values
}

/// A single CSS rule and the highest-specificity selector that resulted in a given match.
type MatchedRule<'a> = (&'a Selector, &'a Rule);

/// Find all CSS rules that match the given element.
fn matching_rules<'a>(elem: &ElementData, stylesheet: &'a Stylesheet) -> Vec<MatchedRule<'a>> {
    // For now, we just do a linear scan of all the rules.  For large
    // documents, it would be more efficient to store the rules in hash tables
    // based on tag name, id, class, etc.
    stylesheet.rules.iter()
        .filter_map(|rule| {
            // Find the first (highest-specificity) matching selector.
            rule.selectors.iter().find(|selector| matches(elem, *selector))
                .map(|selector| (selector, rule))
        }).collect()
}

/// Selector matching:
fn matches(elem: &ElementData, selector: &Selector) -> bool {
    match *selector {
        Simple(ref simple_selector) => matches_simple_selector(elem, simple_selector)
    }
}

fn matches_simple_selector(elem: &ElementData, selector: &SimpleSelector) -> bool {
    // Check type selector
    if selector.tag_name.iter().any(|name| elem.tag_name != *name) {
        return false;
    }

    // Check ID selector
    if selector.id.iter().any(|id| {
        elem.id().iter().any(|elem_id| {
            *elem_id != id
    })}) {
        return false;
    }

    // Check class selectors
    let elem_classes = elem.classes();
    if selector.class.iter().any(|class| !elem_classes.contains(&class.as_slice())) {
        return false;
    }

    // We didn't find any non-matching selector components.
    return true;
}
<|endoftext|>


<commit_before><commit_msg>added flip Cell life status method to world<commit_after><|endoftext|>


<commit_before><commit_msg>Module to save the remote content into a local file<commit_after>use {SChunks};
use std::io::Error;
use std::fs::File;
use std::io::Write;

/// This function takes as parameter a file name and a vector of chaunks.
/// The function will create a file, and append to the buffer each chunk.
pub fn write_file(name_file: &str, chunks: &SChunks) -> Result<(), Error> {

    // Create the file - check if it doesn't exists
    let mut local_file = File::create(name_file).unwrap();

    // Get the access to the chunks
    let chunks_m = chunks.lock().unwrap();

    // For each ones, write it into the file buffer
    for chunk in chunks_m.iter() {
        match local_file.write_all(chunk) {
            Ok(_) => (),
            // Exit if there is an error
            Err(error) => return Err(error),
        }
    }

    // Return a positive result if the remote content has been saved
    Ok(())
}<|endoftext|>


<commit_before><commit_msg>slicing using byte offsets<commit_after><|endoftext|>


<commit_before>/*!

Without bindless textures, using a texture in a shader requires binding the texture to a specific
bind point before drawing. This not only slows down rendering, but may also prevent you from
grouping multiple draw calls into one because of the limitation to the number of available
texture units.

Instead, bindless textures allow you to manually manipulate pointers to textures in video memory.
You can use thousands of textures if you want.

# Initialization

Before using a bindless texture, you must turn it into a `ResidentTexture`. This is done by
calling `resident` on the texture you want.

Bindless textures are a very recent feature that is supported only by recent hardware and
drivers. `resident` will return an `Err` if this feature is not supported.

```no_run
# let display: glium::Display = unsafe { std::mem::uninitialized() };
# let texture: glium::texture::Texture2d = unsafe { std::mem::uninitialized() };
let texture = texture.resident().unwrap();
```

In a real application, you will likely manage a `Vec<ResidentTexture>`.

# Usage

You can then use a `TextureHandle` as if it was a pointer to a texture. A `TextureHandle` can be
built from a `&ResidentTexture` and can't outlive it.

```ignore       // TODO: doctest ICEs on Rust 1.1 (but not on nightly, so this can be `no_run` eventually)
#[macro_use]
extern crate glium;

# fn main() {
#[derive(Copy, Clone)]
struct UniformBuffer<'a> {
    texture: glium::texture::TextureHandle<'a>,
    some_value: f32,
}

implement_uniform_block!(UniformBuffer<'a>, texture, some_value);

# let display: glium::Display = unsafe { std::mem::uninitialized() };
# let texture: glium::texture::bindless::ResidentTexture = unsafe { std::mem::uninitialized() };
let uniform_buffer = glium::uniforms::UniformBuffer::new(&display, UniformBuffer {
    texture: glium::texture::TextureHandle::new(&texture, &Default::default()),
    some_value: 5.0,
});
# }
```

Inside your shader, you can refer to the texture with a traditional `sampler*` variable. Glium
currently doesn't check whether the type of your texture matches the expected type (but it may
do in the future). Binding the wrong type of texture may lead to undefined values when sampling
the texture.

*/
use texture::any::TextureAny;
use TextureExt;
use GlObject;

use ContextExt;
use gl;

use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

use program::BlockLayout;
use uniforms::AsUniformValue;
use uniforms::LayoutMismatchError;
use uniforms::UniformBlock;
use uniforms::UniformValue;
use uniforms::UniformType;
use uniforms::SamplerBehavior;

/// A texture that is resident in video memory. This allows you to use bindless textures in your
/// shaders.
pub struct ResidentTexture {
    texture: Option<TextureAny>,
    handle: gl::types::GLuint64,
}

impl ResidentTexture {
    /// Takes ownership of the given texture and makes it resident.
    // TODO: sampler
    pub fn new(texture: TextureAny) -> Result<ResidentTexture, BindlessTexturesNotSupportedError> {
        let handle = {
            let mut ctxt = texture.get_context().make_current();

            if !ctxt.extensions.gl_arb_bindless_texture {
                return Err(BindlessTexturesNotSupportedError);
            }

            let handle = unsafe { ctxt.gl.GetTextureHandleARB(texture.get_id()) };
            unsafe { ctxt.gl.MakeTextureHandleResidentARB(handle) };
            ctxt.resident_texture_handles.push(handle);
            handle
        };

        // store the handle in the context
        Ok(ResidentTexture {
            texture: Some(texture),
            handle: handle,
        })
    }

    /// Unwraps the texture and restores it.
    #[inline]
    pub fn into_inner(mut self) -> TextureAny {
        self.into_inner_impl()
    }

    /// Implementation of `into_inner`. Also called by the destructor.
    fn into_inner_impl(&mut self) -> TextureAny {
        let texture = self.texture.take().unwrap();

        {
            let mut ctxt = texture.get_context().make_current();
            unsafe { ctxt.gl.MakeTextureHandleNonResidentARB(self.handle) };
            ctxt.resident_texture_handles.retain(|&t| t != self.handle);
        }

        texture
    }
}

impl Deref for ResidentTexture {
    type Target = TextureAny;

    #[inline]
    fn deref(&self) -> &TextureAny {
        self.texture.as_ref().unwrap()
    }
}

impl DerefMut for ResidentTexture {
    #[inline]
    fn deref_mut(&mut self) -> &mut TextureAny {
        self.texture.as_mut().unwrap()
    }
}

impl Drop for ResidentTexture {
    #[inline]
    fn drop(&mut self) {
        self.into_inner_impl();
    }
}

/// Represents a handle to a texture. Contains a raw pointer to a texture that is hidden from you.
#[derive(Copy, Clone)]
pub struct TextureHandle<'a> {
    value: gl::types::GLuint64,
    marker: PhantomData<&'a ResidentTexture>,
}

impl<'a> TextureHandle<'a> {
    /// Builds a new handle.
    #[inline]
    pub fn new(texture: &'a ResidentTexture, _: &SamplerBehavior) -> TextureHandle<'a> {
        // FIXME: take sampler into account
        TextureHandle {
            value: texture.handle,
            marker: PhantomData,
        }
    }

    /// Sets the value to the given texture.
    #[inline]
    pub fn set(&mut self, texture: &'a ResidentTexture, _: &SamplerBehavior) {
        // FIXME: take sampler into account
        self.value = texture.handle;
    }
}

impl<'a> AsUniformValue for TextureHandle<'a> {
    #[inline]
    fn as_uniform_value(&self) -> UniformValue {
        // TODO: u64
        unimplemented!();
    }
}

impl<'a> UniformBlock for TextureHandle<'a> {
    fn matches(layout: &BlockLayout, base_offset: usize)
               -> Result<(), LayoutMismatchError>
    {
        if let &BlockLayout::BasicType { ty, offset_in_buffer } = layout {
            // TODO: unfortunately we have no idea what the exact type of this handle is
            //       strong typing should be considered
            //
            //       however there is no safety problem here ; the worse that can happen in case of
            //       wrong type is zeroes or undefined data being returned when sampling
            match ty {
                UniformType::Sampler1d => (),
                UniformType::ISampler1d => (),
                UniformType::USampler1d => (),
                UniformType::Sampler2d => (),
                UniformType::ISampler2d => (),
                UniformType::USampler2d => (),
                UniformType::Sampler3d => (),
                UniformType::ISampler3d => (),
                UniformType::USampler3d => (),
                UniformType::Sampler1dArray => (),
                UniformType::ISampler1dArray => (),
                UniformType::USampler1dArray => (),
                UniformType::Sampler2dArray => (),
                UniformType::ISampler2dArray => (),
                UniformType::USampler2dArray => (),
                UniformType::SamplerCube => (),
                UniformType::ISamplerCube => (),
                UniformType::USamplerCube => (),
                UniformType::Sampler2dRect => (),
                UniformType::ISampler2dRect => (),
                UniformType::USampler2dRect => (),
                UniformType::Sampler2dRectShadow => (),
                UniformType::SamplerCubeArray => (),
                UniformType::ISamplerCubeArray => (),
                UniformType::USamplerCubeArray => (),
                UniformType::SamplerBuffer => (),
                UniformType::ISamplerBuffer => (),
                UniformType::USamplerBuffer => (),
                UniformType::Sampler2dMultisample => (),
                UniformType::ISampler2dMultisample => (),
                UniformType::USampler2dMultisample => (),
                UniformType::Sampler2dMultisampleArray => (),
                UniformType::ISampler2dMultisampleArray => (),
                UniformType::USampler2dMultisampleArray => (),
                UniformType::Sampler1dShadow => (),
                UniformType::Sampler2dShadow => (),
                UniformType::SamplerCubeShadow => (),
                UniformType::Sampler1dArrayShadow => (),
                UniformType::Sampler2dArrayShadow => (),
                UniformType::SamplerCubeArrayShadow => (),

                _ => return Err(LayoutMismatchError::TypeMismatch {
                    expected: ty,
                    obtained: UniformType::Sampler2d,       // TODO: wrong
                })
            }

            if offset_in_buffer != base_offset {
                return Err(LayoutMismatchError::OffsetMismatch {
                    expected: offset_in_buffer,
                    obtained: base_offset,
                });
            }

            Ok(())

        } else if let &BlockLayout::Struct { ref members } = layout {
            if members.len() == 1 {
                <TextureHandle as UniformBlock>::matches(&members[0].1, base_offset)

            } else {
                Err(LayoutMismatchError::LayoutMismatch {
                    expected: layout.clone(),
                    obtained: BlockLayout::BasicType {
                        ty: UniformType::Sampler2d,       // TODO: wrong
                        offset_in_buffer: base_offset,
                    }
                })
            }

        } else {
            Err(LayoutMismatchError::LayoutMismatch {
                expected: layout.clone(),
                obtained: BlockLayout::BasicType {
                    ty: UniformType::Sampler2d,       // TODO: wrong
                    offset_in_buffer: base_offset,
                }
            })
        }
    }

    #[inline]
    fn build_layout(base_offset: usize) -> BlockLayout {
        BlockLayout::BasicType {
            ty: UniformType::Sampler2d,       // TODO: wrong
            offset_in_buffer: base_offset,
        }
    }
}

// TODO: implement `vertex::Attribute` on `TextureHandle`

/// Bindless textures are not supported.
#[derive(Debug, Copy, Clone)]
pub struct BindlessTexturesNotSupportedError;

#[cfg(test)]
mod test {
    use std::mem;
    use super::TextureHandle;

    #[test]
    fn texture_handle_size() {
        assert_eq!(mem::size_of::<TextureHandle>(), 8);
    }
}
<commit_msg>Fix the doctest in bindless textures's doc<commit_after>/*!

Without bindless textures, using a texture in a shader requires binding the texture to a specific
bind point before drawing. This not only slows down rendering, but may also prevent you from
grouping multiple draw calls into one because of the limitation to the number of available
texture units.

Instead, bindless textures allow you to manually manipulate pointers to textures in video memory.
You can use thousands of textures if you want.

# Initialization

Before using a bindless texture, you must turn it into a `ResidentTexture`. This is done by
calling `resident` on the texture you want.

Bindless textures are a very recent feature that is supported only by recent hardware and
drivers. `resident` will return an `Err` if this feature is not supported.

```no_run
# let display: glium::Display = unsafe { std::mem::uninitialized() };
# let texture: glium::texture::Texture2d = unsafe { std::mem::uninitialized() };
let texture = texture.resident().unwrap();
```

In a real application, you will likely manage a `Vec<ResidentTexture>`.

# Usage

You can then use a `TextureHandle` as if it was a pointer to a texture. A `TextureHandle` can be
built from a `&ResidentTexture` and can't outlive it.

```no_run
#[macro_use]
extern crate glium;

# fn main() {
#[derive(Copy, Clone)]
struct UniformBuffer<'a> {
    texture: glium::texture::TextureHandle<'a>,
    some_value: f32,
}

implement_uniform_block!(UniformBuffer<'a>, texture, some_value);

# let display: glium::Display = unsafe { std::mem::uninitialized() };
# let texture: glium::texture::bindless::ResidentTexture = unsafe { std::mem::uninitialized() };
let uniform_buffer = glium::uniforms::UniformBuffer::new(&display, UniformBuffer {
    texture: glium::texture::TextureHandle::new(&texture, &Default::default()),
    some_value: 5.0,
});
# }
```

Inside your shader, you can refer to the texture with a traditional `sampler*` variable. Glium
currently doesn't check whether the type of your texture matches the expected type (but it may
do in the future). Binding the wrong type of texture may lead to undefined values when sampling
the texture.

*/
use texture::any::TextureAny;
use TextureExt;
use GlObject;

use ContextExt;
use gl;

use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};

use program::BlockLayout;
use uniforms::AsUniformValue;
use uniforms::LayoutMismatchError;
use uniforms::UniformBlock;
use uniforms::UniformValue;
use uniforms::UniformType;
use uniforms::SamplerBehavior;

/// A texture that is resident in video memory. This allows you to use bindless textures in your
/// shaders.
pub struct ResidentTexture {
    texture: Option<TextureAny>,
    handle: gl::types::GLuint64,
}

impl ResidentTexture {
    /// Takes ownership of the given texture and makes it resident.
    // TODO: sampler
    pub fn new(texture: TextureAny) -> Result<ResidentTexture, BindlessTexturesNotSupportedError> {
        let handle = {
            let mut ctxt = texture.get_context().make_current();

            if !ctxt.extensions.gl_arb_bindless_texture {
                return Err(BindlessTexturesNotSupportedError);
            }

            let handle = unsafe { ctxt.gl.GetTextureHandleARB(texture.get_id()) };
            unsafe { ctxt.gl.MakeTextureHandleResidentARB(handle) };
            ctxt.resident_texture_handles.push(handle);
            handle
        };

        // store the handle in the context
        Ok(ResidentTexture {
            texture: Some(texture),
            handle: handle,
        })
    }

    /// Unwraps the texture and restores it.
    #[inline]
    pub fn into_inner(mut self) -> TextureAny {
        self.into_inner_impl()
    }

    /// Implementation of `into_inner`. Also called by the destructor.
    fn into_inner_impl(&mut self) -> TextureAny {
        let texture = self.texture.take().unwrap();

        {
            let mut ctxt = texture.get_context().make_current();
            unsafe { ctxt.gl.MakeTextureHandleNonResidentARB(self.handle) };
            ctxt.resident_texture_handles.retain(|&t| t != self.handle);
        }

        texture
    }
}

impl Deref for ResidentTexture {
    type Target = TextureAny;

    #[inline]
    fn deref(&self) -> &TextureAny {
        self.texture.as_ref().unwrap()
    }
}

impl DerefMut for ResidentTexture {
    #[inline]
    fn deref_mut(&mut self) -> &mut TextureAny {
        self.texture.as_mut().unwrap()
    }
}

impl Drop for ResidentTexture {
    #[inline]
    fn drop(&mut self) {
        self.into_inner_impl();
    }
}

/// Represents a handle to a texture. Contains a raw pointer to a texture that is hidden from you.
#[derive(Copy, Clone)]
pub struct TextureHandle<'a> {
    value: gl::types::GLuint64,
    marker: PhantomData<&'a ResidentTexture>,
}

impl<'a> TextureHandle<'a> {
    /// Builds a new handle.
    #[inline]
    pub fn new(texture: &'a ResidentTexture, _: &SamplerBehavior) -> TextureHandle<'a> {
        // FIXME: take sampler into account
        TextureHandle {
            value: texture.handle,
            marker: PhantomData,
        }
    }

    /// Sets the value to the given texture.
    #[inline]
    pub fn set(&mut self, texture: &'a ResidentTexture, _: &SamplerBehavior) {
        // FIXME: take sampler into account
        self.value = texture.handle;
    }
}

impl<'a> AsUniformValue for TextureHandle<'a> {
    #[inline]
    fn as_uniform_value(&self) -> UniformValue {
        // TODO: u64
        unimplemented!();
    }
}

impl<'a> UniformBlock for TextureHandle<'a> {
    fn matches(layout: &BlockLayout, base_offset: usize)
               -> Result<(), LayoutMismatchError>
    {
        if let &BlockLayout::BasicType { ty, offset_in_buffer } = layout {
            // TODO: unfortunately we have no idea what the exact type of this handle is
            //       strong typing should be considered
            //
            //       however there is no safety problem here ; the worse that can happen in case of
            //       wrong type is zeroes or undefined data being returned when sampling
            match ty {
                UniformType::Sampler1d => (),
                UniformType::ISampler1d => (),
                UniformType::USampler1d => (),
                UniformType::Sampler2d => (),
                UniformType::ISampler2d => (),
                UniformType::USampler2d => (),
                UniformType::Sampler3d => (),
                UniformType::ISampler3d => (),
                UniformType::USampler3d => (),
                UniformType::Sampler1dArray => (),
                UniformType::ISampler1dArray => (),
                UniformType::USampler1dArray => (),
                UniformType::Sampler2dArray => (),
                UniformType::ISampler2dArray => (),
                UniformType::USampler2dArray => (),
                UniformType::SamplerCube => (),
                UniformType::ISamplerCube => (),
                UniformType::USamplerCube => (),
                UniformType::Sampler2dRect => (),
                UniformType::ISampler2dRect => (),
                UniformType::USampler2dRect => (),
                UniformType::Sampler2dRectShadow => (),
                UniformType::SamplerCubeArray => (),
                UniformType::ISamplerCubeArray => (),
                UniformType::USamplerCubeArray => (),
                UniformType::SamplerBuffer => (),
                UniformType::ISamplerBuffer => (),
                UniformType::USamplerBuffer => (),
                UniformType::Sampler2dMultisample => (),
                UniformType::ISampler2dMultisample => (),
                UniformType::USampler2dMultisample => (),
                UniformType::Sampler2dMultisampleArray => (),
                UniformType::ISampler2dMultisampleArray => (),
                UniformType::USampler2dMultisampleArray => (),
                UniformType::Sampler1dShadow => (),
                UniformType::Sampler2dShadow => (),
                UniformType::SamplerCubeShadow => (),
                UniformType::Sampler1dArrayShadow => (),
                UniformType::Sampler2dArrayShadow => (),
                UniformType::SamplerCubeArrayShadow => (),

                _ => return Err(LayoutMismatchError::TypeMismatch {
                    expected: ty,
                    obtained: UniformType::Sampler2d,       // TODO: wrong
                })
            }

            if offset_in_buffer != base_offset {
                return Err(LayoutMismatchError::OffsetMismatch {
                    expected: offset_in_buffer,
                    obtained: base_offset,
                });
            }

            Ok(())

        } else if let &BlockLayout::Struct { ref members } = layout {
            if members.len() == 1 {
                <TextureHandle as UniformBlock>::matches(&members[0].1, base_offset)

            } else {
                Err(LayoutMismatchError::LayoutMismatch {
                    expected: layout.clone(),
                    obtained: BlockLayout::BasicType {
                        ty: UniformType::Sampler2d,       // TODO: wrong
                        offset_in_buffer: base_offset,
                    }
                })
            }

        } else {
            Err(LayoutMismatchError::LayoutMismatch {
                expected: layout.clone(),
                obtained: BlockLayout::BasicType {
                    ty: UniformType::Sampler2d,       // TODO: wrong
                    offset_in_buffer: base_offset,
                }
            })
        }
    }

    #[inline]
    fn build_layout(base_offset: usize) -> BlockLayout {
        BlockLayout::BasicType {
            ty: UniformType::Sampler2d,       // TODO: wrong
            offset_in_buffer: base_offset,
        }
    }
}

// TODO: implement `vertex::Attribute` on `TextureHandle`

/// Bindless textures are not supported.
#[derive(Debug, Copy, Clone)]
pub struct BindlessTexturesNotSupportedError;

#[cfg(test)]
mod test {
    use std::mem;
    use super::TextureHandle;

    #[test]
    fn texture_handle_size() {
        assert_eq!(mem::size_of::<TextureHandle>(), 8);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add pop function for first linked list<commit_after><|endoftext|>


<commit_before><commit_msg>Commit file<commit_after>
use std::io;
use std::clone::Clone;
use std::slice::Iter;
use std::collections::hash_map::HashMap;

use parser::ast::*;
use parser::util::allocate_element_key;
use output::structs::*;
// use output::client_js::*;
use output::client_misc::*;
use output::client_output::*;
use output::client_ops_writer::*;

#[derive(Debug)]
pub struct ElementOpsHtmlStreamWriter<'input> {
    pub util: WriteElementOpsUtilImpl<'input>,
    pub events_vec: EventsVec,
    pub keys_vec: Vec<String>,
}

impl<'input: 'scope, 'scope> ElementOpsHtmlStreamWriter<'input> {

    #[inline]
    pub fn with_doc(doc: &'input DocumentState<'input>) -> Self {
        ElementOpsHtmlStreamWriter {
            util: WriteElementOpsUtilImpl::with_doc(doc),
            events_vec: Default::default(),
            keys_vec: Default::default()
        }
    }

    #[inline]
    #[allow(unused_variables)]
    fn write_html_js_action(&mut self, w: &mut io::Write, act_iter: Iter<ActionOpNode>) -> Result {
        write!(w, "function(event) {{")?;
        for ref act_op in act_iter {
            match *act_op {
                &ActionOpNode::DispatchAction(ref action, ref params) => {
                    //let action_type = resolve.action_type(Some(action));
                    write!(w, " store.dispatch({{\"type\": \"{}\"}}); ", action)?;
                }
            }
        }
        write!(w, "}}")?;
        Ok(())
    }

    #[inline]
    fn write_element_attribute_expr_value(&mut self, w: &mut io::Write, key: &str, expr: &'input ExprValue) -> Result {
        match expr {
            &ExprValue::Expr(ExprOp::Add, ref l, ref r) => {}

            &ExprValue::DefaultAction(ref params, ref act_ops) => {
                if let &Some(ref act_ops) = act_ops {
                    self.write_html_js_action(w, act_ops.iter())?;
                };
            }
            &ExprValue::Action(ref event_name, ref params, ref act_ops) => {
                if let &Some(ref act_ops) = act_ops {
                    self.write_html_js_action(w, act_ops.iter())?;
                };
            }
            _ => {
                write!(w, "\"")?;
                write_computed_expr_value(w, expr, None, None)?;
                write!(w, "\"")?;
            }
        };
        Ok(())
    }
}

impl<'input: 'scope, 'scope> ElementOpsStreamWriter<'input> for ElementOpsHtmlStreamWriter<'input> {
    fn write_op_element(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, element_key: &'input str, element_tag: &'input str, is_void: bool, attrs: Option<Iter<Prop>>, events: Option<Iter<EventHandler>>) -> Result {
        let base_key = scope.base_element_key(element_key);

        write!(w, "<{}", element_tag)?;
        write!(w, " data-id=\"{}\"", base_key)?;
        write!(w, " key=\"{}\"", base_key)?;

        if let Some(ref attrs) = attrs {
            for &(ref key, ref expr) in *attrs {
                // Ignore empty attributes
                if let &Some(ref expr) = expr {
                    self.write_element_attribute_expr_value(w, key, expr)?;
                };
            }
        };

        if is_void {
            write!(w, " />")?;
        } else {
            write!(w, ">")?;
        };

        // Process events
        if let Some(ref events) = events {
            for &(ref event_name, ref event_params, ref action_ops) in *events {
                let event_params = event_params.as_ref().map(|event_params| event_params.iter().cloned().collect());
                let action_ops = action_ops.as_ref().map(|action_ops| action_ops.iter().cloned().collect());
                let event_name = event_name.as_ref().map(Clone::clone);

                // let cur_scope = resolve.cur_scope.as_ref().map(|s| format!("{}", s));
                self.events_vec.push((base_key.clone(),
                                        event_name,
                                        event_params,
                                        action_ops,
                                        self.util.scope().key()));
            }
        }

        self.keys_vec.push(base_key);
        Ok(())
    }

    #[inline]
    fn write_op_element_close(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, element_tag: &'input str) -> Result {
        write!(w, "</{}>", element_tag)?;
        Ok(())
    }

    #[inline]
    fn write_op_element_value(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, expr: &ExprValue, value_key: &'input str) -> Result {
        let element_key = scope.base_element_key(value_key);
        write!(w, "", element_key, element_key)?;
        write_computed_expr_value(w, expr, None, None)?;
        write!(w, "")?;

        self.keys_vec.push(element_key);
        Ok(())
    }

    #[inline]
    fn write_op_element_start_block(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, block_id: &str) -> Result {
        // TODO: What should this be in HTML output?
        Ok(())
    }

    #[inline]
    fn write_op_element_end_block(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, block_id: &str) -> Result {
        // TODO: What should this be in HTML output?
        Ok(())
    }

    #[inline]
    fn write_op_element_map_collection_to_block(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, coll_expr: &'input ExprValue, block_id: &str) -> Result {
        // TODO: What should this be in HTML output?
        Ok(())
    }

    #[inline]
    fn write_op_element_instance_component_open(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, comp: &'input Component<'input>, component_key: &str, component_id: &str, attrs: Option<Iter<Prop>>, lens: Option<&str>) -> Result {
        let base_key = scope.base_element_key(component_key);
        self.keys_vec.push(base_key);

        write!(w, "
", base_key, base_key)?;
        Ok(())
    }

    #[inline]
    fn write_op_element_instance_component_close(&mut self, w: &mut io::Write, op: &'input ElementOp, doc: &DocumentState, scope: &Scope, comp: &'input Component<'input>, component_key: &str, component_id: &str) -> Result {
        write!(w, "
")?;
        Ok(())
    }
}<|endoftext|>


<commit_before><commit_msg>Make CharacterAttributes::image optional instead<commit_after><|endoftext|>


<commit_before><commit_msg>Add serialize to structs<commit_after><|endoftext|>


<commit_before>use std::env::*;
use std::env;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::ascii::AsciiExt;
use hyper::Client;
use hyper::header::Connection;
use hyper::client::response::Response;

extern crate rustc_serialize;
use self::rustc_serialize::json::*;

#[derive(Clone, Debug)]
pub struct AWSCredentials {
    key: String,
    secret: String
}

#[derive(Debug)]
enum CredentialErr {
    NoEnvironmentVariables,
    NoCredentialsFile,
}

struct ProfileCredentialsError;

impl AWSCredentials {
    pub fn new(key:&str, secret:&str) -> AWSCredentials {
        AWSCredentials {
            key: key.to_string(),
            secret: secret.to_string()
        }
    }

    pub fn get_aws_access_key_id(&self) -> &str {
    	&self.key
    }

    pub fn get_aws_secret_key(&self) -> &str {
    	&self.secret
    }
}

// TODO: refactor get_credentials to return std::result
pub trait AWSCredentialsProvider {
    fn new() -> Self;
	fn get_credentials(&self) -> &AWSCredentials;
	fn refresh(&mut self);
}

// class for environment
pub struct EnvironmentCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for EnvironmentCredentialsProvider {
    fn new() -> EnvironmentCredentialsProvider {
        return EnvironmentCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

	fn refresh(&mut self) {
        let env_key = match var("AWS_ACCESS_KEY_ID") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };
        let env_secret = match var("AWS_SECRET_ACCESS_KEY") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };

        self.credentials = AWSCredentials{key: env_key, secret: env_secret};
	}

	fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

// class for file based
pub struct FileCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for FileCredentialsProvider {
    fn new() -> FileCredentialsProvider {
        return FileCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

	fn refresh(&mut self) {
        // Default credentials file location:
        // ~/.aws/credentials (Linux/Mac)
        // %USERPROFILE%\.aws\credentials  (Windows)
        let mut profile_location = String::new();
        match env::home_dir() {
            Some(ref p) => profile_location = p.display().to_string() + "/.aws/credentials",
            None => {
                println!("Couldn't get your home dir.");
                self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string() };
                return;
            }
        }
        let credentials = get_credentials_from_file(profile_location);
        self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
    }

    fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

// Finds and uses the first "aws_access_key_id" and "aws_secret_access_key" in the file.
fn get_credentials_from_file(file_with_path: String) -> AWSCredentials {
    println!("Looking for credentials file at {}", file_with_path);
    let path = Path::new(&file_with_path);
    let display = path.display();

    let mut found_file = false;

    match fs::metadata(&path) {
        Err(why) => println!("Couldn't get metadata for file: {}", why),
        Ok(metadata) => found_file = metadata.is_file()
    };

    // bail early.  Should be converted to a return type.
    if !found_file {
        return AWSCredentials{ key: "".to_string(), secret: "".to_string() };
    }

    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(opened_file) => opened_file,
    };

    let mut access_key = String::new();
    let mut secret_key = String::new();
    let file_lines = BufReader::new(&file);
    for line in file_lines.lines() {
        let unwrapped_line : String = line.unwrap();
        // Skip line if it starts with a comment ('#')
        if unwrapped_line.starts_with('#') {
            continue;
        }

        let lower_case_line = unwrapped_line.to_ascii_lowercase().to_string();

        if lower_case_line.contains("aws_access_key_id") {
            if access_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    access_key = "".to_string();
                } else {
                    access_key = v[1].trim_matches(' ').to_string();
                }
            }
        } else if lower_case_line.contains("aws_secret_access_key") {
            if secret_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    secret_key = "".to_string();
                } else {
                    secret_key = v[1].trim_matches(' ').to_string();
                }
            }
        }
    }

    return AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string() };
}

// class for IAM role
pub struct IAMRoleCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for IAMRoleCredentialsProvider {
    fn new() -> IAMRoleCredentialsProvider {
        return IAMRoleCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

	fn refresh(&mut self) {
        // call instance metadata to get iam role
        // curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
        // sample result:
        // fooprofile

        // for "real" use: http://169.254.169.254/latest/meta-data/iam/security-credentials/
        let mut address : String = "http://localhost:8080/latest/meta-data/iam/security-credentials".to_string();
        println!("Checking {} for credentials.", address);
        let client = Client::new();
        let mut response;
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(why) => {
                    println!("boo, request failed: {}", why);
                    return;
                }
                Ok(received_response) => response = received_response
            };
        println!("request made");

        let mut body = String::new();
        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading response: {}", why),
            Ok(_) => (),
        };

        // use results to make another call:
        // curl http://169.254.169.254/latest/meta-data/iam/security-credentials/fooprofile

        // sample results:
        // {
        //   "Code" : "Success",
        //   "LastUpdated" : "2015-08-04T00:09:23Z",
        //   "Type" : "AWS-HMAC",
        //   "AccessKeyId" : "AAAAAA",
        //   "SecretAccessKey" : "AAAAA",
        //   "Token" : "AAAAA",
        //   "Expiration" : "2015-08-04T06:32:37Z"
        // }

        // add body to location:
        address.push_str("/");
        address.push_str(&body);
        println!("Making request to {}", address);
        body = String::new();
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(_) => return,
                Ok(received_response) => response = received_response
            };

        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading iam role response: {}", why),
            Ok(_) => (),
        };

        // println!("Response for iam role request: {}", body);

        let json_object : Json;
        match Json::from_str(&body) {
            Err(why) => {
                println!("Error: {}", why);
                return;
            }
            Ok(val) => json_object = val
        };

        let mut access_key = String::new();
        match json_object.find("AccessKeyId") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => access_key = val.to_string()
        };

        let mut secret_key = String::new();
        match json_object.find("SecretAccessKey") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => secret_key = val.to_string()
        };

        self.credentials = AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string() };
    }

    fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct DefaultAWSCredentialsProviderChain {
    credentials: AWSCredentials
}

// Chain the providers:
impl DefaultAWSCredentialsProviderChain {
    pub fn new() -> DefaultAWSCredentialsProviderChain {
        return DefaultAWSCredentialsProviderChain {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

    pub fn get_credentials(&self) -> &AWSCredentials {
        return &self.credentials;
    }

    // This is getting a bit out of control with nested if/else: should try doing something else for flow control.
    pub fn refresh(&mut self) {
        // fetch creds in order: env, file, IAM
        self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string() };

        let mut env_provider = EnvironmentCredentialsProvider::new();
        env_provider.refresh();
        let credentials = env_provider.get_credentials();

        if creds_have_values(credentials) {
            println!("using creds from env: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
            self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
            return;
        } else {
            // try the file provider
            let mut file_provider = FileCredentialsProvider::new();
            file_provider.refresh();
            let credentials = file_provider.get_credentials();
            println!("using creds from file: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());

            if creds_have_values(credentials) {
                self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
            } else {
                let mut iam_provider = IAMRoleCredentialsProvider::new();
                iam_provider.refresh();
                let credentials = iam_provider.get_credentials();
                if creds_have_values(credentials) {
                    println!("using creds from IAM: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
                    self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
                    return;
                } else {
                    // We're out of options
                    panic!("Couldn't find AWS credentials in environment, default credential file location or IAM role.");
                }
            }
        }
    }
}

fn creds_have_values(creds: &AWSCredentials) -> bool {
    if creds.get_aws_access_key_id().len() > 0 && creds.get_aws_secret_key().len() > 0 {
        return true;
    }
    return false;
}
<commit_msg>Removes unneeded comments.<commit_after>use std::env::*;
use std::env;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::error::Error;
use std::io::prelude::*;
use std::io::BufReader;
use std::ascii::AsciiExt;
use hyper::Client;
use hyper::header::Connection;
use hyper::client::response::Response;

extern crate rustc_serialize;
use self::rustc_serialize::json::*;

#[derive(Clone, Debug)]
pub struct AWSCredentials {
    key: String,
    secret: String
}

#[derive(Debug)]
enum CredentialErr {
    NoEnvironmentVariables,
    NoCredentialsFile,
}

struct ProfileCredentialsError;

impl AWSCredentials {
    pub fn new(key:&str, secret:&str) -> AWSCredentials {
        AWSCredentials {
            key: key.to_string(),
            secret: secret.to_string()
        }
    }

    pub fn get_aws_access_key_id(&self) -> &str {
    	&self.key
    }

    pub fn get_aws_secret_key(&self) -> &str {
    	&self.secret
    }
}

// TODO: refactor get_credentials to return std::result
pub trait AWSCredentialsProvider {
    fn new() -> Self;
	fn get_credentials(&self) -> &AWSCredentials;
	fn refresh(&mut self);
}

pub struct EnvironmentCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for EnvironmentCredentialsProvider {
    fn new() -> EnvironmentCredentialsProvider {
        return EnvironmentCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

	fn refresh(&mut self) {
        let env_key = match var("AWS_ACCESS_KEY_ID") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };
        let env_secret = match var("AWS_SECRET_ACCESS_KEY") {
            Ok(val) => val,
            Err(_) => "".to_string()
        };

        self.credentials = AWSCredentials{key: env_key, secret: env_secret};
	}

	fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct FileCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for FileCredentialsProvider {
    fn new() -> FileCredentialsProvider {
        return FileCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

	fn refresh(&mut self) {
        // Default credentials file location:
        // ~/.aws/credentials (Linux/Mac)
        // %USERPROFILE%\.aws\credentials  (Windows)
        let mut profile_location = String::new();
        match env::home_dir() {
            Some(ref p) => profile_location = p.display().to_string() + "/.aws/credentials",
            None => {
                println!("Couldn't get your home dir.");
                self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string() };
                return;
            }
        }
        let credentials = get_credentials_from_file(profile_location);
        self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
    }

    fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

// Finds and uses the first "aws_access_key_id" and "aws_secret_access_key" in the file.
fn get_credentials_from_file(file_with_path: String) -> AWSCredentials {
    println!("Looking for credentials file at {}", file_with_path);
    let path = Path::new(&file_with_path);
    let display = path.display();

    let mut found_file = false;

    match fs::metadata(&path) {
        Err(why) => println!("Couldn't get metadata for file: {}", why),
        Ok(metadata) => found_file = metadata.is_file()
    };

    // bail early.  Should be converted to a return type.
    if !found_file {
        return AWSCredentials{ key: "".to_string(), secret: "".to_string() };
    }

    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", display, Error::description(&why)),
        Ok(opened_file) => opened_file,
    };

    let mut access_key = String::new();
    let mut secret_key = String::new();
    let file_lines = BufReader::new(&file);
    for line in file_lines.lines() {
        let unwrapped_line : String = line.unwrap();
        // Skip line if it starts with a comment ('#')
        if unwrapped_line.starts_with('#') {
            continue;
        }

        let lower_case_line = unwrapped_line.to_ascii_lowercase().to_string();

        if lower_case_line.contains("aws_access_key_id") {
            if access_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    access_key = "".to_string();
                } else {
                    access_key = v[1].trim_matches(' ').to_string();
                }
            }
        } else if lower_case_line.contains("aws_secret_access_key") {
            if secret_key.is_empty() {
                let v: Vec<&str> = unwrapped_line.split("=").collect();
                if v.len() == 0 {
                    secret_key = "".to_string();
                } else {
                    secret_key = v[1].trim_matches(' ').to_string();
                }
            }
        }
    }

    return AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string() };
}

// class for IAM role
pub struct IAMRoleCredentialsProvider {
    credentials: AWSCredentials
}

impl AWSCredentialsProvider for IAMRoleCredentialsProvider {
    fn new() -> IAMRoleCredentialsProvider {
        return IAMRoleCredentialsProvider {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

	fn refresh(&mut self) {
        // call instance metadata to get iam role
        // curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
        // sample result:
        // fooprofile

        // for "real" use: http://169.254.169.254/latest/meta-data/iam/security-credentials/
        let mut address : String = "http://localhost:8080/latest/meta-data/iam/security-credentials".to_string();
        println!("Checking {} for credentials.", address);
        let client = Client::new();
        let mut response;
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(why) => {
                    println!("boo, request failed: {}", why);
                    return;
                }
                Ok(received_response) => response = received_response
            };
        println!("request made");

        let mut body = String::new();
        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading response: {}", why),
            Ok(_) => (),
        };

        // use results to make another call:
        // curl http://169.254.169.254/latest/meta-data/iam/security-credentials/fooprofile

        // sample results:
        // {
        //   "Code" : "Success",
        //   "LastUpdated" : "2015-08-04T00:09:23Z",
        //   "Type" : "AWS-HMAC",
        //   "AccessKeyId" : "AAAAAA",
        //   "SecretAccessKey" : "AAAAA",
        //   "Token" : "AAAAA",
        //   "Expiration" : "2015-08-04T06:32:37Z"
        // }

        // add body to location:
        address.push_str("/");
        address.push_str(&body);
        println!("Making request to {}", address);
        body = String::new();
        match client.get(&address)
            .header(Connection::close()).send() {
                Err(_) => return,
                Ok(received_response) => response = received_response
            };

        match response.read_to_string(&mut body) {
            Err(why) => println!("Had issues with reading iam role response: {}", why),
            Ok(_) => (),
        };

        // println!("Response for iam role request: {}", body);

        let json_object : Json;
        match Json::from_str(&body) {
            Err(why) => {
                println!("Error: {}", why);
                return;
            }
            Ok(val) => json_object = val
        };

        let mut access_key = String::new();
        match json_object.find("AccessKeyId") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => access_key = val.to_string()
        };

        let mut secret_key = String::new();
        match json_object.find("SecretAccessKey") {
            None => {
                println!("Error finding AccessKeyId");
                return;
            }
            Some(val) => secret_key = val.to_string()
        };

        self.credentials = AWSCredentials{ key: access_key.to_string(), secret: secret_key.to_string() };
    }

    fn get_credentials(&self) -> &AWSCredentials {
		return &self.credentials;
	}
}

pub struct DefaultAWSCredentialsProviderChain {
    credentials: AWSCredentials
}

// Chain the providers:
impl DefaultAWSCredentialsProviderChain {
    pub fn new() -> DefaultAWSCredentialsProviderChain {
        return DefaultAWSCredentialsProviderChain {credentials: AWSCredentials{ key: "".to_string(), secret: "".to_string() } };
    }

    pub fn get_credentials(&self) -> &AWSCredentials {
        return &self.credentials;
    }

    // This is getting a bit out of control with nested if/else: should try doing something else for flow control.
    pub fn refresh(&mut self) {
        // fetch creds in order: env, file, IAM
        self.credentials = AWSCredentials{ key: "".to_string(), secret: "".to_string() };

        let mut env_provider = EnvironmentCredentialsProvider::new();
        env_provider.refresh();
        let credentials = env_provider.get_credentials();

        if creds_have_values(credentials) {
            println!("using creds from env: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
            self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
            return;
        } else {
            // try the file provider
            let mut file_provider = FileCredentialsProvider::new();
            file_provider.refresh();
            let credentials = file_provider.get_credentials();
            println!("using creds from file: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());

            if creds_have_values(credentials) {
                self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
            } else {
                let mut iam_provider = IAMRoleCredentialsProvider::new();
                iam_provider.refresh();
                let credentials = iam_provider.get_credentials();
                if creds_have_values(credentials) {
                    println!("using creds from IAM: {}, {}", credentials.get_aws_access_key_id(), credentials.get_aws_secret_key());
                    self.credentials = AWSCredentials{ key: credentials.get_aws_access_key_id().to_string(), secret: credentials.get_aws_secret_key().to_string() };
                    return;
                } else {
                    // We're out of options
                    panic!("Couldn't find AWS credentials in environment, default credential file location or IAM role.");
                }
            }
        }
    }
}

fn creds_have_values(creds: &AWSCredentials) -> bool {
    if creds.get_aws_access_key_id().len() > 0 && creds.get_aws_secret_key().len() > 0 {
        return true;
    }
    return false;
}
<|endoftext|>


<commit_before><commit_msg>Fix naming issue<commit_after><|endoftext|>


<commit_before><commit_msg>tests: incomplete_rss: distinct display and description<commit_after><|endoftext|>


<commit_before>extern crate difference;
extern crate cobalt;
extern crate walkdir;

use std::path::Path;
use std::fs::{self, File};
use std::io::Read;
use walkdir::WalkDir;
use std::error::Error;

fn run_test(name: &str) -> Result<(), cobalt::Error> {
    let source = format!("tests/fixtures/{}/", name);
    let target = format!("tests/target/{}/", name);
    let dest = format!("tests/tmp/{}/", name);

    let result = cobalt::build(&Path::new(&source), &Path::new(&dest), "_layouts", "_posts");

    if result.is_ok() {
        let walker = WalkDir::new(&target).into_iter();

        // walk through fixture and created tmp directory and compare files
        for entry in walker.filter_map(|e| e.ok()).filter(|e| e.file_type().is_file()) {
            let relative = entry.path().to_str().unwrap().split(&target).last().unwrap();

            let mut original = String::new();
            File::open(entry.path()).unwrap().read_to_string(&mut original).unwrap();

            let mut created = String::new();
            File::open(&Path::new(&dest).join(&relative))
                .unwrap()
                .read_to_string(&mut created)
                .unwrap();

            difference::assert_diff(&original, &created, " ", 0);
        }

        // clean up
        fs::remove_dir_all(dest).expect("Cleanup failed");
    }

    result
}

#[test]
pub fn example() {
    assert!(run_test("example").is_ok());
}

#[test]
pub fn dotfiles() {
    assert!(run_test("dotfiles").is_ok());
}

#[test]
pub fn liquid_error() {
    let err = run_test("liquid_error");
    assert!(err.is_err());
    assert_eq!(err.unwrap_err().description(), "{{{ is not a valid identifier");
}

#[test]
pub fn no_extends_error() {
    let err = run_test("no_extends_error");
    assert!(err.is_err());
    assert_eq!(err.unwrap_err().description(), "No @extends line creating _posts/2014-08-24-my-first-blogpost.md");
}

<commit_msg>undoing an overlooked newline<commit_after>extern crate difference;
extern crate cobalt;
extern crate walkdir;

use std::path::Path;
use std::fs::{self, File};
use std::io::Read;
use walkdir::WalkDir;
use std::error::Error;

fn run_test(name: &str) -> Result<(), cobalt::Error> {
    let source = format!("tests/fixtures/{}/", name);
    let target = format!("tests/target/{}/", name);
    let dest = format!("tests/tmp/{}/", name);

    let result = cobalt::build(&Path::new(&source), &Path::new(&dest), "_layouts", "_posts");

    if result.is_ok() {
        let walker = WalkDir::new(&target).into_iter();

        // walk through fixture and created tmp directory and compare files
        for entry in walker.filter_map(|e| e.ok()).filter(|e| e.file_type().is_file()) {
            let relative = entry.path().to_str().unwrap().split(&target).last().unwrap();

            let mut original = String::new();
            File::open(entry.path()).unwrap().read_to_string(&mut original).unwrap();

            let mut created = String::new();
            File::open(&Path::new(&dest).join(&relative))
                .unwrap()
                .read_to_string(&mut created)
                .unwrap();

            difference::assert_diff(&original, &created, " ", 0);
        }

        // clean up
        fs::remove_dir_all(dest).expect("Cleanup failed");
    }

    result
}

#[test]
pub fn example() {
    assert!(run_test("example").is_ok());
}

#[test]
pub fn dotfiles() {
    assert!(run_test("dotfiles").is_ok());
}

#[test]
pub fn liquid_error() {
    let err = run_test("liquid_error");
    assert!(err.is_err());
    assert_eq!(err.unwrap_err().description(), "{{{ is not a valid identifier");
}

#[test]
pub fn no_extends_error() {
    let err = run_test("no_extends_error");
    assert!(err.is_err());
    assert_eq!(err.unwrap_err().description(), "No @extends line creating _posts/2014-08-24-my-first-blogpost.md");
}
<|endoftext|>


<commit_before><commit_msg>Fix compilation.<commit_after><|endoftext|>


<commit_before><commit_msg>Renaming BMPPalette to Palette<commit_after><|endoftext|>


<commit_before>use std::io::{Read};

use getopts;

use hyper::{Client};
use hyper::status::{StatusCode};

use rustc_serialize::{json};

use super::{CreateServiceResult, Service, ServiceFactory, ServiceResult, User};

#[derive(RustcDecodable)]
struct SlackUserListResponse {
    ok: bool,
    members: Vec<SlackUser>,
}

#[derive(RustcDecodable)]
struct SlackUser {
    name: String,
    deleted: bool,
    is_bot: Option<bool>,
    has_2fa: Option<bool>,
    profile: SlackProfile,
    is_owner: Option<bool>,
    is_admin: Option<bool>,
}

#[derive(RustcDecodable)]
struct SlackProfile {
    email: Option<String>,
}

pub struct SlackServiceFactory;

impl ServiceFactory for SlackServiceFactory {
    fn add_options(&self, opts: &mut getopts::Options) {
        opts.optopt(
            "", "slack-token", "Slack token (https://api.slack.com/web#authentication)", "token"
        );
    }

    fn create_service(&self, matches: &getopts::Matches) -> CreateServiceResult {
        match matches.opt_str("slack-token") {
            Some(token) => CreateServiceResult::Service(Box::new(SlackService{
                token: token
            })),
            None => CreateServiceResult::None,
        }
    }
}

struct SlackService {
    token: String,
}

impl Service for SlackService {
    fn get_users(&self) -> ServiceResult {
        let client = Client::new();

        let mut response = client.get(
            &format!("https://slack.com/api/users.list?token={}", self.token)
        ).send().unwrap();
        assert_eq!(response.status, StatusCode::Ok);
        let mut body = String::new();
        response.read_to_string(&mut body).unwrap();

        let result = json::decode::<SlackUserListResponse>(&body).unwrap();
        assert!(result.ok);
        let users = result.members.iter().filter(|user| {
            match (user.deleted, user.is_bot, user.has_2fa) {
                (true, _, _) => false,
                (false, Some(true), _) => false,
                (false, _, None) => true,
                (false, _, Some(true)) => false,
                (false, _, Some(false)) => true,
            }
        }).map(|user|
            User{
                name: user.name.to_string(),
                email: Some(user.profile.email.clone().unwrap()),
                details: match (user.is_owner.unwrap(), user.is_admin.unwrap()) {
                    (true, true) => Some("Owner/Admin".to_string()),
                    (true, false) => Some("Owner".to_string()),
                    (false, true) => Some("Admin".to_string()),
                    (false, false) => None
                }
            }
        ).collect();

        return ServiceResult{
            service_name: "Slack".to_string(),
            users: users,
        }
    }
}
<commit_msg>simplify code<commit_after>use std::io::{Read};

use getopts;

use hyper::{Client};
use hyper::status::{StatusCode};

use rustc_serialize::{json};

use super::{CreateServiceResult, Service, ServiceFactory, ServiceResult, User};

#[derive(RustcDecodable)]
struct SlackUserListResponse {
    ok: bool,
    members: Vec<SlackUser>,
}

#[derive(RustcDecodable)]
struct SlackUser {
    name: String,
    deleted: bool,
    is_bot: Option<bool>,
    has_2fa: Option<bool>,
    profile: SlackProfile,
    is_owner: Option<bool>,
    is_admin: Option<bool>,
}

#[derive(RustcDecodable)]
struct SlackProfile {
    email: Option<String>,
}

pub struct SlackServiceFactory;

impl ServiceFactory for SlackServiceFactory {
    fn add_options(&self, opts: &mut getopts::Options) {
        opts.optopt(
            "", "slack-token", "Slack token (https://api.slack.com/web#authentication)", "token"
        );
    }

    fn create_service(&self, matches: &getopts::Matches) -> CreateServiceResult {
        match matches.opt_str("slack-token") {
            Some(token) => CreateServiceResult::Service(Box::new(SlackService{
                token: token
            })),
            None => CreateServiceResult::None,
        }
    }
}

struct SlackService {
    token: String,
}

impl Service for SlackService {
    fn get_users(&self) -> ServiceResult {
        let client = Client::new();

        let mut response = client.get(
            &format!("https://slack.com/api/users.list?token={}", self.token)
        ).send().unwrap();
        assert_eq!(response.status, StatusCode::Ok);
        let mut body = String::new();
        response.read_to_string(&mut body).unwrap();

        let result = json::decode::<SlackUserListResponse>(&body).unwrap();
        assert!(result.ok);
        let users = result.members.iter().filter(|user| {
            match user.deleted {
                true => false,
                false => match user.is_bot.unwrap() {
                    true => false,
                    false => !user.has_2fa.unwrap(),
                }
            }
        }).map(|user|
            User{
                name: user.name.to_string(),
                email: Some(user.profile.email.clone().unwrap()),
                details: match (user.is_owner.unwrap(), user.is_admin.unwrap()) {
                    (true, true) => Some("Owner/Admin".to_string()),
                    (true, false) => Some("Owner".to_string()),
                    (false, true) => Some("Admin".to_string()),
                    (false, false) => None
                }
            }
        ).collect();

        return ServiceResult{
            service_name: "Slack".to_string(),
            users: users,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added in a little documentation for the function added in last commit, as well as a test.<commit_after><|endoftext|>


<commit_before><commit_msg>add_history_persist<commit_after><|endoftext|>