<commit_before>extern crate gcc;

use std::process::Command;
use std::env;

fn debug() -> bool {
    match env::var("DEBUG") {
        Ok(s) => s == "true",
        Err(_) => false
    }
}

fn mode() -> &'static str {
    if debug() { "Debug" } else { "Release" }
}

fn object_path(libname: &str) -> String {
    format!("build/{}/obj.target/{}/src/{}.o", mode(), libname, libname)
}

fn build_object_file() {
    // Ensure that all package.json dependencies and dev dependencies are installed.
    Command::new("npm").arg("install").status().ok()
        .expect(r#"failed to run "npm install" for neon-sys"#);

    // Run the package.json `configure` script, which invokes `node-gyp configure` from the local node_modules.
    Command::new("npm").arg("run").arg(if debug() { "configure-debug" } else { "configure-release" }).status().ok().unwrap();

    // Run the package.json `build` script, which invokes `node-gyp build` from the local node_modules.
    Command::new("npm").arg("run").arg(if debug() { "build-debug" } else { "build-release" }).status().ok().unwrap();
}

fn link_library() {
    // Link the built object file into a static library.
    gcc::Config::new()
        .object(object_path("neon"))
        .compile("libneon.a");
}

fn main() {
    // 1. Build the object file from source using node-gyp.
    build_object_file();

    // 2. Link the library from the object file using gcc.
    link_library();
}
<commit_msg>Fix object file path on windows<commit_after>extern crate gcc;

use std::process::Command;
use std::env;

fn debug() -> bool {
    match env::var("DEBUG") {
        Ok(s) => s == "true",
        Err(_) => false
    }
}

fn mode() -> &'static str {
    if debug() { "Debug" } else { "Release" }
}

#[cfg(not(windows))]
fn object_path(libname: &str) -> String {
    format!("build/{}/obj.target/{}/src/{}.o", mode(), libname, libname)
}

#[cfg(windows)]
fn object_path(libname: &str) -> String {
    format!("build\\{}\\obj\\{}\\{}.obj", mode(), libname, libname)
}

fn build_object_file() {
    // Ensure that all package.json dependencies and dev dependencies are installed.
    Command::new("npm").arg("install").status().ok()
        .expect(r#"failed to run "npm install" for neon-sys"#);

    // Run the package.json `configure` script, which invokes `node-gyp configure` from the local node_modules.
    Command::new("npm").arg("run").arg(if debug() { "configure-debug" } else { "configure-release" }).status().ok().unwrap();

    // Run the package.json `build` script, which invokes `node-gyp build` from the local node_modules.
    Command::new("npm").arg("run").arg(if debug() { "build-debug" } else { "build-release" }).status().ok().unwrap();
}

fn link_library() {
    // Link the built object file into a static library.
    gcc::Config::new()
        .object(object_path("neon"))
        .compile("libneon.a");
}

fn main() {
    // 1. Build the object file from source using node-gyp.
    build_object_file();

    // 2. Link the library from the object file using gcc.
    link_library();
}
<|endoftext|>


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

use std;
use std::fmt;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::process::{Child, ExitStatus};
use std::result;

use hcore;
use hcore::service::ServiceGroup;
use serde::{Serialize, Serializer};

use super::health;
use error::Result;
use manager::service::ServiceConfig;
use supervisor::RuntimeConfig;
use templating::Template;
use util;

pub const HOOK_PERMISSIONS: u32 = 0o755;
static LOGKEY: &'static str = "HK";

#[derive(Debug, Copy, Clone)]
pub struct ExitCode(i32);

impl Default for ExitCode {
    fn default() -> ExitCode {
        ExitCode(-1)
    }
}

pub trait Hook: fmt::Debug + Sized {
    type ExitValue: Default;

    fn file_name() -> &'static str;

    fn load<C, T>(service_group: &ServiceGroup, concrete_path: C, template_path: T) -> Option<Self>
        where C: AsRef<Path>,
              T: AsRef<Path>
    {
        let concrete = concrete_path.as_ref().join(Self::file_name());
        let template = template_path.as_ref().join(Self::file_name());
        match std::fs::metadata(&template) {
            Ok(_) => {
                match Self::new(concrete, template) {
                    Ok(hook) => Some(hook),
                    Err(err) => {
                        outputln!(preamble service_group, "Failed to load hook: {}", err);
                        None
                    }
                }
            }
            Err(_) => {
                debug!("{} not found at {}, not loading",
                       Self::file_name(),
                       template.display());
                None
            }
        }
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>;

    /// Compile a hook into it's destination service directory.
    fn compile(&self, cfg: &ServiceConfig) -> Result<()> {
        let toml = try!(cfg.to_toml());
        let svc_data = util::convert::toml_to_json(toml);
        let data = try!(self.template().render("hook", &svc_data));
        let mut file = try!(std::fs::File::create(self.path()));
        try!(file.write_all(data.as_bytes()));
        try!(hcore::util::perm::set_owner(self.path(), &cfg.pkg.svc_user, &cfg.pkg.svc_group));
        try!(hcore::util::perm::set_permissions(self.path(), HOOK_PERMISSIONS));
        debug!("{} compiled to {}",
               Self::file_name(),
               self.path().display());
        Ok(())
    }

    /// Run a compiled hook.
    fn run(&self, service_group: &ServiceGroup, cfg: &RuntimeConfig) -> Self::ExitValue {
        let mut child = match util::create_command(self.path(), &cfg.svc_user, &cfg.svc_group)
            .spawn() {
            Ok(child) => child,
            Err(err) => {
                outputln!(preamble service_group,
                    "Hook failed to run, {}, {}", Self::file_name(), err);
                return Self::ExitValue::default();
            }
        };
        stream_output::<Self>(service_group, &mut child);
        match child.wait() {
            Ok(status) => self.handle_exit(service_group, &status),
            Err(err) => {
                outputln!(preamble service_group,
                    "Hook failed to run, {}, {}", Self::file_name(), err);
                Self::ExitValue::default()
            }
        }
    }

    fn handle_exit(&self, group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue;

    fn path(&self) -> &Path;

    fn template(&self) -> &Template;
}

#[derive(Debug, Serialize)]
pub struct FileUpdatedHook(RenderPair);

impl Hook for FileUpdatedHook {
    type ExitValue = bool;

    fn file_name() -> &'static str {
        "file_updated"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(FileUpdatedHook(pair))
    }

    fn handle_exit(&self, _: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        status.success()
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct HealthCheckHook(RenderPair);

impl Hook for HealthCheckHook {
    type ExitValue = health::HealthCheck;

    fn file_name() -> &'static str {
        "health_check"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(HealthCheckHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(0) => health::HealthCheck::Ok,
            Some(1) => health::HealthCheck::Warning,
            Some(2) => health::HealthCheck::Critical,
            Some(3) => health::HealthCheck::Unknown,
            Some(code) => {
                outputln!(preamble service_group,
                    "Health check exited with an unknown status code, {}", code);
                health::HealthCheck::default()
            }
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                health::HealthCheck::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct InitHook(RenderPair);

impl Hook for InitHook {
    type ExitValue = ExitCode;

    fn file_name() -> &'static str {
        "init"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(InitHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(code) => ExitCode(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                ExitCode::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct ReconfigureHook(RenderPair);

impl Hook for ReconfigureHook {
    type ExitValue = ExitCode;

    fn file_name() -> &'static str {
        "reconfigure"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(ReconfigureHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(code) => ExitCode(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                ExitCode::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct RunHook(RenderPair);

impl Hook for RunHook {
    type ExitValue = ExitCode;

    fn file_name() -> &'static str {
        "run"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(RunHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(code) => ExitCode(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                ExitCode::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct SmokeTestHook(RenderPair);

impl Hook for SmokeTestHook {
    type ExitValue = health::SmokeCheck;

    fn file_name() -> &'static str {
        "smoke_test"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(SmokeTestHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(0) => health::SmokeCheck::Ok,
            Some(code) => health::SmokeCheck::Failed(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                health::SmokeCheck::Failed(-1)
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Default, Serialize)]
pub struct HookTable {
    pub health_check: Option<HealthCheckHook>,
    pub init: Option<InitHook>,
    pub file_updated: Option<FileUpdatedHook>,
    pub reconfigure: Option<ReconfigureHook>,
    pub run: Option<RunHook>,
    pub smoke_test: Option<SmokeTestHook>,
    cfg_incarnation: u64,
}

impl HookTable {
    /// Compile all loaded hooks from the table into their destination service directory.
    pub fn compile(&mut self, service_group: &ServiceGroup, config: &ServiceConfig) {
        if self.cfg_incarnation != 0 && config.incarnation <= self.cfg_incarnation {
            debug!("{}, Hooks already compiled with the latest configuration incarnation, \
                    skipping",
                   service_group);
            return;
        }
        self.cfg_incarnation = config.incarnation;
        if let Some(ref hook) = self.file_updated {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.health_check {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.init {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.reconfigure {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.run {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.smoke_test {
            self.compile_one(hook, service_group, config);
        }
        debug!("{}, Hooks compiled", service_group);
    }

    /// Read all available hook templates from the table's package directory into the table.
    pub fn load_hooks<T, U>(mut self, service_group: &ServiceGroup, hooks: T, templates: U) -> Self
        where T: AsRef<Path>,
              U: AsRef<Path>
    {
        if let Some(meta) = std::fs::metadata(templates.as_ref()).ok() {
            if meta.is_dir() {
                self.file_updated = FileUpdatedHook::load(service_group, &hooks, &templates);
                self.health_check = HealthCheckHook::load(service_group, &hooks, &templates);
                self.init = InitHook::load(service_group, &hooks, &templates);
                self.reconfigure = ReconfigureHook::load(service_group, &hooks, &templates);
                self.run = RunHook::load(service_group, &hooks, &templates);
                self.smoke_test = SmokeTestHook::load(service_group, &hooks, &templates);
            }
        }
        debug!("{}, Hooks loaded, destination={}, templates={}",
               service_group,
               hooks.as_ref().display(),
               templates.as_ref().display());
        self
    }

    fn compile_one<H>(&self, hook: &H, service_group: &ServiceGroup, config: &ServiceConfig)
        where H: Hook
    {
        hook.compile(config).unwrap_or_else(|e| {
            outputln!(preamble service_group,
                "Failed to compile {} hook: {}", H::file_name(), e);
        });
    }
}

struct RenderPair {
    path: PathBuf,
    template: Template,
}

impl RenderPair {
    pub fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let mut template = Template::new();
        template.register_template_file("hook", template_path.as_ref())?;
        Ok(RenderPair {
            path: concrete_path.into(),
            template: template,
        })
    }
}

impl fmt::Debug for RenderPair {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "path: {}", self.path.display())
    }
}

impl Serialize for RenderPair {
    fn serialize<S>(&self, serializer: &mut S) -> result::Result<(), S::Error>
        where S: Serializer
    {
        serializer.serialize_str(&self.path.as_os_str().to_string_lossy().into_owned())
    }
}

fn stream_output<H: Hook>(service_group: &ServiceGroup, process: &mut Child) {
    let preamble_str = stream_preamble::<H>(service_group);
    if let Some(ref mut stdout) = process.stdout {
        for line in BufReader::new(stdout).lines() {
            if let Some(ref l) = line.ok() {
                outputln!(preamble preamble_str, l);
            }
        }
    }
    if let Some(ref mut stderr) = process.stderr {
        for line in BufReader::new(stderr).lines() {
            if let Some(ref l) = line.ok() {
                outputln!(preamble preamble_str, l);
            }
        }
    }
}

fn stream_preamble<H: Hook>(service_group: &ServiceGroup) -> String {
    format!("{} hook[{}]:", service_group, H::file_name())
}
<commit_msg>[sup] Fix a `Serialize` trait impl for serde 0.9.<commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std;
use std::fmt;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::process::{Child, ExitStatus};
use std::result;

use hcore;
use hcore::service::ServiceGroup;
use serde::{Serialize, Serializer};

use super::health;
use error::Result;
use manager::service::ServiceConfig;
use supervisor::RuntimeConfig;
use templating::Template;
use util;

pub const HOOK_PERMISSIONS: u32 = 0o755;
static LOGKEY: &'static str = "HK";

#[derive(Debug, Copy, Clone)]
pub struct ExitCode(i32);

impl Default for ExitCode {
    fn default() -> ExitCode {
        ExitCode(-1)
    }
}

pub trait Hook: fmt::Debug + Sized {
    type ExitValue: Default;

    fn file_name() -> &'static str;

    fn load<C, T>(service_group: &ServiceGroup, concrete_path: C, template_path: T) -> Option<Self>
        where C: AsRef<Path>,
              T: AsRef<Path>
    {
        let concrete = concrete_path.as_ref().join(Self::file_name());
        let template = template_path.as_ref().join(Self::file_name());
        match std::fs::metadata(&template) {
            Ok(_) => {
                match Self::new(concrete, template) {
                    Ok(hook) => Some(hook),
                    Err(err) => {
                        outputln!(preamble service_group, "Failed to load hook: {}", err);
                        None
                    }
                }
            }
            Err(_) => {
                debug!("{} not found at {}, not loading",
                       Self::file_name(),
                       template.display());
                None
            }
        }
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>;

    /// Compile a hook into it's destination service directory.
    fn compile(&self, cfg: &ServiceConfig) -> Result<()> {
        let toml = try!(cfg.to_toml());
        let svc_data = util::convert::toml_to_json(toml);
        let data = try!(self.template().render("hook", &svc_data));
        let mut file = try!(std::fs::File::create(self.path()));
        try!(file.write_all(data.as_bytes()));
        try!(hcore::util::perm::set_owner(self.path(), &cfg.pkg.svc_user, &cfg.pkg.svc_group));
        try!(hcore::util::perm::set_permissions(self.path(), HOOK_PERMISSIONS));
        debug!("{} compiled to {}",
               Self::file_name(),
               self.path().display());
        Ok(())
    }

    /// Run a compiled hook.
    fn run(&self, service_group: &ServiceGroup, cfg: &RuntimeConfig) -> Self::ExitValue {
        let mut child = match util::create_command(self.path(), &cfg.svc_user, &cfg.svc_group)
            .spawn() {
            Ok(child) => child,
            Err(err) => {
                outputln!(preamble service_group,
                    "Hook failed to run, {}, {}", Self::file_name(), err);
                return Self::ExitValue::default();
            }
        };
        stream_output::<Self>(service_group, &mut child);
        match child.wait() {
            Ok(status) => self.handle_exit(service_group, &status),
            Err(err) => {
                outputln!(preamble service_group,
                    "Hook failed to run, {}, {}", Self::file_name(), err);
                Self::ExitValue::default()
            }
        }
    }

    fn handle_exit(&self, group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue;

    fn path(&self) -> &Path;

    fn template(&self) -> &Template;
}

#[derive(Debug, Serialize)]
pub struct FileUpdatedHook(RenderPair);

impl Hook for FileUpdatedHook {
    type ExitValue = bool;

    fn file_name() -> &'static str {
        "file_updated"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(FileUpdatedHook(pair))
    }

    fn handle_exit(&self, _: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        status.success()
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct HealthCheckHook(RenderPair);

impl Hook for HealthCheckHook {
    type ExitValue = health::HealthCheck;

    fn file_name() -> &'static str {
        "health_check"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(HealthCheckHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(0) => health::HealthCheck::Ok,
            Some(1) => health::HealthCheck::Warning,
            Some(2) => health::HealthCheck::Critical,
            Some(3) => health::HealthCheck::Unknown,
            Some(code) => {
                outputln!(preamble service_group,
                    "Health check exited with an unknown status code, {}", code);
                health::HealthCheck::default()
            }
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                health::HealthCheck::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct InitHook(RenderPair);

impl Hook for InitHook {
    type ExitValue = ExitCode;

    fn file_name() -> &'static str {
        "init"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(InitHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(code) => ExitCode(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                ExitCode::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct ReconfigureHook(RenderPair);

impl Hook for ReconfigureHook {
    type ExitValue = ExitCode;

    fn file_name() -> &'static str {
        "reconfigure"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(ReconfigureHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(code) => ExitCode(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                ExitCode::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct RunHook(RenderPair);

impl Hook for RunHook {
    type ExitValue = ExitCode;

    fn file_name() -> &'static str {
        "run"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(RunHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(code) => ExitCode(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                ExitCode::default()
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Serialize)]
pub struct SmokeTestHook(RenderPair);

impl Hook for SmokeTestHook {
    type ExitValue = health::SmokeCheck;

    fn file_name() -> &'static str {
        "smoke_test"
    }

    fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let pair = RenderPair::new(concrete_path, template_path)?;
        Ok(SmokeTestHook(pair))
    }

    fn handle_exit(&self, service_group: &ServiceGroup, status: &ExitStatus) -> Self::ExitValue {
        match status.code() {
            Some(0) => health::SmokeCheck::Ok,
            Some(code) => health::SmokeCheck::Failed(code),
            None => {
                outputln!(preamble service_group,
                    "{} exited without a status code", Self::file_name());
                health::SmokeCheck::Failed(-1)
            }
        }
    }

    fn path(&self) -> &Path {
        &self.0.path
    }

    fn template(&self) -> &Template {
        &self.0.template
    }
}

#[derive(Debug, Default, Serialize)]
pub struct HookTable {
    pub health_check: Option<HealthCheckHook>,
    pub init: Option<InitHook>,
    pub file_updated: Option<FileUpdatedHook>,
    pub reconfigure: Option<ReconfigureHook>,
    pub run: Option<RunHook>,
    pub smoke_test: Option<SmokeTestHook>,
    cfg_incarnation: u64,
}

impl HookTable {
    /// Compile all loaded hooks from the table into their destination service directory.
    pub fn compile(&mut self, service_group: &ServiceGroup, config: &ServiceConfig) {
        if self.cfg_incarnation != 0 && config.incarnation <= self.cfg_incarnation {
            debug!("{}, Hooks already compiled with the latest configuration incarnation, \
                    skipping",
                   service_group);
            return;
        }
        self.cfg_incarnation = config.incarnation;
        if let Some(ref hook) = self.file_updated {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.health_check {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.init {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.reconfigure {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.run {
            self.compile_one(hook, service_group, config);
        }
        if let Some(ref hook) = self.smoke_test {
            self.compile_one(hook, service_group, config);
        }
        debug!("{}, Hooks compiled", service_group);
    }

    /// Read all available hook templates from the table's package directory into the table.
    pub fn load_hooks<T, U>(mut self, service_group: &ServiceGroup, hooks: T, templates: U) -> Self
        where T: AsRef<Path>,
              U: AsRef<Path>
    {
        if let Some(meta) = std::fs::metadata(templates.as_ref()).ok() {
            if meta.is_dir() {
                self.file_updated = FileUpdatedHook::load(service_group, &hooks, &templates);
                self.health_check = HealthCheckHook::load(service_group, &hooks, &templates);
                self.init = InitHook::load(service_group, &hooks, &templates);
                self.reconfigure = ReconfigureHook::load(service_group, &hooks, &templates);
                self.run = RunHook::load(service_group, &hooks, &templates);
                self.smoke_test = SmokeTestHook::load(service_group, &hooks, &templates);
            }
        }
        debug!("{}, Hooks loaded, destination={}, templates={}",
               service_group,
               hooks.as_ref().display(),
               templates.as_ref().display());
        self
    }

    fn compile_one<H>(&self, hook: &H, service_group: &ServiceGroup, config: &ServiceConfig)
        where H: Hook
    {
        hook.compile(config).unwrap_or_else(|e| {
            outputln!(preamble service_group,
                "Failed to compile {} hook: {}", H::file_name(), e);
        });
    }
}

struct RenderPair {
    path: PathBuf,
    template: Template,
}

impl RenderPair {
    pub fn new<C, T>(concrete_path: C, template_path: T) -> Result<Self>
        where C: Into<PathBuf>,
              T: AsRef<Path>
    {
        let mut template = Template::new();
        template.register_template_file("hook", template_path.as_ref())?;
        Ok(RenderPair {
            path: concrete_path.into(),
            template: template,
        })
    }
}

impl fmt::Debug for RenderPair {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "path: {}", self.path.display())
    }
}

impl Serialize for RenderPair {
    fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
        where S: Serializer
    {
        serializer.serialize_str(&self.path.as_os_str().to_string_lossy().into_owned())
    }
}

fn stream_output<H: Hook>(service_group: &ServiceGroup, process: &mut Child) {
    let preamble_str = stream_preamble::<H>(service_group);
    if let Some(ref mut stdout) = process.stdout {
        for line in BufReader::new(stdout).lines() {
            if let Some(ref l) = line.ok() {
                outputln!(preamble preamble_str, l);
            }
        }
    }
    if let Some(ref mut stderr) = process.stderr {
        for line in BufReader::new(stderr).lines() {
            if let Some(ref l) = line.ok() {
                outputln!(preamble preamble_str, l);
            }
        }
    }
}

fn stream_preamble<H: Hook>(service_group: &ServiceGroup) -> String {
    format!("{} hook[{}]:", service_group, H::file_name())
}
<|endoftext|>


<commit_before>// Copyright 2018 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.

// ignore-wasm32
// ignore-emscripten

#![feature(const_fn)]
#![allow(const_err)]

use std::env;
use std::process::{Command, Stdio};

const fn bar() -> usize { 0 - 1 }

fn foo() {
    let _: &'static _ = &bar();
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 && args[1] == "test" {
        foo();
        return;
    }

    let mut p = Command::new(&args[0])
        .stdout(Stdio::piped())
        .stdin(Stdio::piped())
        .arg("test").output().unwrap();
    assert!(!p.status.success());
}
<commit_msg>Auto merge of #52823 - RalfJung:test, r=eddyb<commit_after>// Copyright 2018 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.

// ignore-wasm32
// ignore-emscripten

#![feature(const_fn, libc)]
#![allow(const_err)]

extern crate libc;

use std::env;
use std::process::{Command, Stdio};

// this will panic in debug mode
const fn bar() -> usize { 0 - 1 }

fn foo() {
    let _: &'static _ = &bar();
}

#[cfg(unix)]
fn check_status(status: std::process::ExitStatus)
{
    use libc;
    use std::os::unix::process::ExitStatusExt;

    assert!(status.signal() == Some(libc::SIGILL)
            || status.signal() == Some(libc::SIGABRT));
}

#[cfg(not(unix))]
fn check_status(status: std::process::ExitStatus)
{
    assert!(!status.success());
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() > 1 && args[1] == "test" {
        foo();
        return;
    }

    let mut p = Command::new(&args[0])
        .stdout(Stdio::piped())
        .stdin(Stdio::piped())
        .arg("test").output().unwrap();
    check_status(p.status);
}
<|endoftext|>


<commit_before>// Test taking the LUB of two function types that are not equatable but where
// one is more general than the other. Test the case where the more general type
// (`x`) is the second match arm specifically.
//
// Skip for compare-mode because the pure NLL checker accepts this test. (Note
// that it still errors in old-lub-glb-hr-noteq1.rs). What happens is that, due
// to the ordering of the match arms, we pick the correct "more general" fn
// type, and we ignore the errors from the non-NLL type checker that requires
// equality. The NLL type checker only requires a subtyping relationship, and
// that holds.
//
// ignore-compare-mode-nll

fn foo(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) {
    // The two types above are not equivalent. With the older LUB/GLB
    // algorithm, this may have worked (I don't remember), but now it
    // doesn't because we require equality.
    let z = match 22 {
        0 => y,
        _ => x, //~ ERROR `match` arms have incompatible types
    };
}

fn foo_cast(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) {
    // But we can *upcast* explicitly the type of `x` and figure
    // things out:
    let z = match 22 {
        0 => x as for<'a> fn(&'a u8, &'a u8) -> &'a u8,
        _ => y,
    };
}

fn main() {}
<commit_msg>cite issue 73154<commit_after>// Test taking the LUB of two function types that are not equatable but where
// one is more general than the other. Test the case where the more general type
// (`x`) is the second match arm specifically.
//
// FIXME(#73154) Skip for compare-mode because the pure NLL checker accepts this
// test. (Note that it still errors in old-lub-glb-hr-noteq1.rs). What happens
// is that, due to the ordering of the match arms, we pick the correct "more
// general" fn type, and we ignore the errors from the non-NLL type checker that
// requires equality. The NLL type checker only requires a subtyping
// relationship, and that holds.
//
// ignore-compare-mode-nll

fn foo(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) {
    // The two types above are not equivalent. With the older LUB/GLB
    // algorithm, this may have worked (I don't remember), but now it
    // doesn't because we require equality.
    let z = match 22 {
        0 => y,
        _ => x, //~ ERROR `match` arms have incompatible types
    };
}

fn foo_cast(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) {
    // But we can *upcast* explicitly the type of `x` and figure
    // things out:
    let z = match 22 {
        0 => x as for<'a> fn(&'a u8, &'a u8) -> &'a u8,
        _ => y,
    };
}

fn main() {}
<|endoftext|>


<commit_before>//! `StructureTerminal` data description.
use super::super::resources::ResourceType;
use super::super::resources::Store;
use crate::data::RoomName;

with_base_fields_and_update_struct! {
    /// A terminal structure - a structure that has a medium capacity for storing multiple resources,
    /// and can spend energy to send any resources to another room with a terminal instantly.
    // Note: there's a field "send" which seems to always be null. It will be non-existent on a
    // terminal which has never sent any resources, and then will be updated to "null" on the first send.
    #[derive(Clone, Debug, PartialEq)]
    #[serde(rename_all = "camelCase")]
    pub struct StructureTerminal {
        /// The current number of hit-points this structure has.
        #[serde(default)]
        pub hits: i32,
        /// The maximum number of hit-points this structure has.
        #[serde(default)]
        pub hits_max: i32,
        /// The user ID of the owner of this structure.
        pub user: String,
        /// Whether or not this structure is non-functional due to a degraded controller.
        #[serde(default, rename = "off")]
        pub disabled: bool,
        /// Total capacity for this structure.
        #[serde(rename = "storeCapacity")]
        pub capacity: i32,
        /// The game time at which this terminal will next be able to send minerals.
        #[serde(default)]
        pub cooldown_time: u32,
        /// Whether or not an attack on this structure will send an email to the owner automatically.
        pub notify_when_attacked: bool,
        /// The resources and amounts of each resource some game object holds.
        pub store: Store,
    }

    /// The update structure for an extension structure.
    #[derive(Clone, Debug)]
    #[serde(rename_all = "camelCase")]
    pub struct StructureTerminalUpdate {
        - hits: i32,
        - hits_max: i32,
        - user: String,
        #[serde(rename = "off")]
        - disabled: bool,
        #[serde(rename = "energyCapacity")]
        - capacity: i32,
        - cooldown_time: u32,
        - notify_when_attacked: bool,
        - store: Store,
    }
}

impl StructureTerminal {
    /// Iterates over this structure's resources.
    pub fn resources(&self) -> impl Iterator<Item = (ResourceType, i32)> + '_ {
        self.store.iter()
    }
}

#[cfg(test)]
mod test {
    use serde::Deserialize;

    use super::StructureTerminal;

    #[test]
    fn parse_terminal() {
        let json = json!({
            "_id": "59a5cc4f4733bb4c785ec4e7",
            "cooldownTime": 38432852,
            "hits": 3000,
            "hitsMax": 3000,
            "notifyWhenAttacked": true,
            "room": "W39N49",
            "send": null,
            "store": {
                "X": 50189,
                "XGH2O": 0,
                "energy": 25000
            },
            "storeCapacity": 300000,
            "type": "terminal",
            "user": "5788389e3fd9069e6b546e2d",
            "x": 4,
            "y": 9
        });

        let obj = StructureTerminal::deserialize(json).unwrap();

        match obj {
            StructureTerminal {
                capacity: 300000,
                hits: 3000,
                hits_max: 3000,
                notify_when_attacked: true,
                cooldown_time: 38432852,
                disabled: false,
                x: 4,
                y: 9,
                ref user,
                ref id,
                ref store,
                ..
            } if user == "5788389e3fd9069e6b546e2d"
                && id == "59a5cc4f4733bb4c785ec4e7"
                && *store == store! {Energy: 25000, Catalyst: 50189} =>
            {
                ()
            }

            other => panic!(
                "expected pre-set StructureTerminal to match, found {:#?}",
                other
            ),
        }
    }

    #[test]
    fn parse_with_null_cooldown() {
        // note: not actual server data, reconstructed from two instances
        //  - it's hard to find a null terminal cooldown.
        let json = json!({
            "_id": "59a5cc4f4733bb4c785ec4e7",
            "hits": 3000,
            "hitsMax": 3000,
            "notifyWhenAttacked": true,
            "room": "W39N49",
            "send": null,
            "store": {},
            "storeCapacity": 300000,
            "type": "terminal",
            "user": "5788389e3fd9069e6b546e2d",
            "x": 4,
            "y": 9
        });

        let obj = StructureTerminal::deserialize(json).unwrap();

        assert_eq!(obj.cooldown_time, 0);
    }

    #[test]
    fn parse_npc_terminal_with_null_store() {
        let json = json!({
            "_id": "57cd3a30c0551957424a1f0b",
            "room": "E40N40",
            "store": {
                "H": null,
                "K": null,
                "L": null,
                "O": null,
                "U": null,
                "X": null,
                "Z": null,
                "energy": 0,
                "power": null
            },
            "storeCapacity": 0,
            "type": "terminal",
            "x": 35,
            "y": 45
        });
        let obj = StructureTerminal::deserialize(json).unwrap();
        assert_eq!(obj.store, store!());
    }
}
<commit_msg>Fixed parse_npc_terminal_with_null_store<commit_after>//! `StructureTerminal` data description.
use super::super::resources::ResourceType;
use super::super::resources::Store;
use crate::data::RoomName;

with_base_fields_and_update_struct! {
    /// A terminal structure - a structure that has a medium capacity for storing multiple resources,
    /// and can spend energy to send any resources to another room with a terminal instantly.
    // Note: there's a field "send" which seems to always be null. It will be non-existent on a
    // terminal which has never sent any resources, and then will be updated to "null" on the first send.
    #[derive(Clone, Debug, PartialEq)]
    #[serde(rename_all = "camelCase")]
    pub struct StructureTerminal {
        /// The current number of hit-points this structure has.
        #[serde(default)]
        pub hits: i32,
        /// The maximum number of hit-points this structure has.
        #[serde(default)]
        pub hits_max: i32,
        /// The user ID of the owner of this structure.
        pub user: Option<String>,
        /// Whether or not this structure is non-functional due to a degraded controller.
        #[serde(default, rename = "off")]
        pub disabled: bool,
        /// Total capacity for this structure.
        #[serde(rename = "storeCapacity")]
        pub capacity: i32,
        /// The game time at which this terminal will next be able to send minerals.
        #[serde(default)]
        pub cooldown_time: u32,
        /// Whether or not an attack on this structure will send an email to the owner automatically.
        pub notify_when_attacked: Option<bool>,
        /// The resources and amounts of each resource some game object holds.
        pub store: Store,
    }

    /// The update structure for an extension structure.
    #[derive(Clone, Debug)]
    #[serde(rename_all = "camelCase")]
    pub struct StructureTerminalUpdate {
        - hits: i32,
        - hits_max: i32,
        - user: Option<String>,
        #[serde(rename = "off")]
        - disabled: bool,
        #[serde(rename = "energyCapacity")]
        - capacity: i32,
        - cooldown_time: u32,
        - notify_when_attacked: Option<bool>,
        - store: Store,
    }
}

impl StructureTerminal {
    /// Iterates over this structure's resources.
    pub fn resources(&self) -> impl Iterator<Item = (ResourceType, i32)> + '_ {
        self.store.iter()
    }
}

#[cfg(test)]
mod test {
    use serde::Deserialize;

    use super::StructureTerminal;

    #[test]
    fn parse_terminal() {
        let json = json!({
            "_id": "59a5cc4f4733bb4c785ec4e7",
            "cooldownTime": 38432852,
            "hits": 3000,
            "hitsMax": 3000,
            "notifyWhenAttacked": true,
            "room": "W39N49",
            "send": null,
            "store": {
                "X": 50189,
                "XGH2O": 0,
                "energy": 25000
            },
            "storeCapacity": 300000,
            "type": "terminal",
            "user": "5788389e3fd9069e6b546e2d",
            "x": 4,
            "y": 9
        });

        let obj = StructureTerminal::deserialize(json).unwrap();

        match obj {
            StructureTerminal {
                capacity: 300000,
                hits: 3000,
                hits_max: 3000,
                notify_when_attacked: Some(true),
                cooldown_time: 38432852,
                disabled: false,
                x: 4,
                y: 9,
                ref user,
                ref id,
                ref store,
                ..
            } if *user == Some("5788389e3fd9069e6b546e2d".to_string())
                && id == "59a5cc4f4733bb4c785ec4e7"
                && *store == store! {Energy: 25000, Catalyst: 50189} =>
            {
                ()
            }

            other => panic!(
                "expected pre-set StructureTerminal to match, found {:#?}",
                other
            ),
        }
    }

    #[test]
    fn parse_with_null_cooldown() {
        // note: not actual server data, reconstructed from two instances
        //  - it's hard to find a null terminal cooldown.
        let json = json!({
            "_id": "59a5cc4f4733bb4c785ec4e7",
            "hits": 3000,
            "hitsMax": 3000,
            "notifyWhenAttacked": true,
            "room": "W39N49",
            "send": null,
            "store": {},
            "storeCapacity": 300000,
            "type": "terminal",
            "user": "5788389e3fd9069e6b546e2d",
            "x": 4,
            "y": 9
        });

        let obj = StructureTerminal::deserialize(json).unwrap();

        assert_eq!(obj.cooldown_time, 0);
    }

    #[test]
    fn parse_npc_terminal_with_null_store() {
        let json = json!({
            "_id": "57cd3a30c0551957424a1f0b",
            "room": "E40N40",
            "store": {
                "H": null,
                "K": null,
                "L": null,
                "O": null,
                "U": null,
                "X": null,
                "Z": null,
                "energy": 0,
                "power": null
            },
            "storeCapacity": 0,
            "type": "terminal",
            "x": 35,
            "y": 45
        });
        let obj = StructureTerminal::deserialize(json).unwrap();
        assert_eq!(obj.store, store!());
    }
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Started structure for toy robot<commit_after>enum Direction {
    North,
    East,
    South,
    West,
    Empty,
}

struct Robot {
    x: i32,
    y: i32,
    d: Direction,
}

impl Default for Robot {
    fn default() -> Robot {
        Robot{x: 0, y: 0, d: Direction::Empty}
    }
}

impl Robot {
    fn place(&self, x: i32, y: i32, d: Direction) {
        println!("Woohoo");
    }
}

fn main() {
    let robot: Robot = Default::default();

    robot.place(1, 2, Direction::North);
}
<|endoftext|>


<commit_before>//First draft of client. no gui, no networking
// This is what the server will do in the back
extern crate rand;
use rand::{Rng, thread_rng};
use std::io::{self, BufRead};
use cardgame_board::*;

use action::*;
use std::sync::mpsc::channel;
use std::sync::mpsc::{Sender, Receiver};

use std::thread;

pub fn gameloop(mut player_1: Player, mut player_2: Player, send_1: Sender<String>, recv_1: Receiver<String>, send_2: Sender<String>, recv_2: Receiver<String>) {

    //We clone these cards so we will keep the originals
    //at the end for persistance

    //Initialize tmp values
    player_1.deck.init();
    player_2.deck.init();

    println!("Starting game");
    player_1.deck.print();

    player_1.deck.save_to_file();

    //Determine the id's
    player_1.id = 1;
    player_2.id = 2;

    let mut game_is_going: bool = true;
    let mut turn: bool = true;

    /* Board initialization*/
    //shuffle both decks
    //TODO: shuffle
    let mut rng = thread_rng();
    rng.shuffle(&mut player_1.deck.cards);
    rng.shuffle(&mut player_2.deck.cards);
    // draw cards for each player
    for _ in 0..6 {
        println!("drawing_cards");
        draw_card(&mut player_1);
        draw_card(&mut player_2);
    }

    let mut curr_sender = &send_1;
    let mut curr_recv = &recv_1;

    player_1.print();
    player_2.print();

    /* Start game */
    while game_is_going {
        //Define who is who
        let mut current_player;
        let mut other_player;
        if turn == true {
            current_player = &mut player_1;
            other_player = &mut player_2;
            curr_sender = &send_1;
            curr_recv = &recv_1;

        } else {
            current_player = &mut player_2;
            other_player = &mut player_1;
            curr_sender = &send_2;
            curr_recv = &recv_2;

        }
        println!("\n#### This player's turn {}", current_player.name);

        //Get a mana point
        current_player.mana += 1;

        current_player.print();
        //First the player draws a card

        draw_card(current_player);

        //Turn starts,
        //unfatigue all cards
        for i in &mut current_player.field {
            i.fatigued = false;
        }
        for i in current_player.field.clone() {
            trigger_ability("on_turn_start".to_owned(),
                            &i.id,
                            &mut current_player,
                            &mut other_player,
                            &curr_sender,
                            &curr_recv);
        }

        let mut doing_things: bool = true;
        while doing_things {

            //Asks what the player wants to do
            //The options are "play", "attack", "look", and "help"
            let mut line = String::new();
            let stdin = io::stdin();
            stdin
                .lock()
                .read_line(&mut line)
                .expect("Could not read line");

            let split = line.split_whitespace();
            let split: Vec<&str> = split.collect();

            if split.is_empty() {
                println!("enter a command, valid commands are \"play\", \"attack\", \"look\", and \"help\"");
            } else if split[0] == "play" {
                let id: i32 = split[1].parse().unwrap();
                play_card(&id,
                          &mut current_player.hand,
                          &mut current_player.field,
                          &current_player.deck,
                          &mut current_player.mana);
                trigger_ability("on_play".to_owned(),
                                &id,
                                &mut current_player,
                                &mut other_player,
                                &curr_sender,
                                &curr_recv);
            } else if split[0] == "attack" {
                //This should all be moved to the board section
                //Make sure enough arguments were supplied
                if split.len() < 3 {
                    println!("not enough arguments, try \"attack your_monster enemy\" to attack opponent, use 999");
                } else {
                    let attacker: i32 = split[1].parse().unwrap();
                    let target: i32 = split[2].parse().unwrap();

                    attack(&attacker, &target, &mut current_player, &mut other_player);
                }
            } else if split[0] == "attack_face" {
                let mut id: i32 = split[1].parse().unwrap();
                attack_face(&mut id, &mut other_player, &mut current_player, &curr_sender, &curr_recv);

            } else if split[0] == "win" {
                game_is_going = false;
                break;
            } else if split[0] == "look" {
                current_player.print();
                println!("\n");
            } else if split[0] == "end" {
                doing_things = false;
            } else {
                println!("enter a command, valid commands are \"play\", \"attack\", \"look\", and \"help\"");
            }

        }

        for i in current_player.field.clone() {
            trigger_ability("on_turn_start".to_owned(),
                            &i.id,
                            &mut current_player,
                            &mut other_player,
                            &curr_sender,
                            &curr_recv);
        }

        if turn == false {
            turn = true;
        } else {
            turn = false;
        }
    }

    player_1.de_init();
    player_2.de_init();
    println!("Game is over");

}
<commit_msg>Changing how code is formated<commit_after>//First draft of client. no gui, no networking
// This is what the server will do in the back
extern crate rand;
use rand::{Rng, thread_rng};
use std::io::{self, BufRead};
use cardgame_board::*;

use action::*;
use std::sync::mpsc::channel;
use std::sync::mpsc::{Sender, Receiver};

use std::thread;

pub fn gameloop(
    mut player_1: Player,
    mut player_2: Player,
    send_1: Sender<String>,
    recv_1: Receiver<String>,
    send_2: Sender<String>,
    recv_2: Receiver<String>,
) {

    //We clone these cards so we will keep the originals
    //at the end for persistance

    //Initialize tmp values
    player_1.deck.init();
    player_2.deck.init();

    println!("Starting game");
    player_1.deck.print();

    player_1.deck.save_to_file();

    //Determine the id's
    player_1.id = 1;
    player_2.id = 2;

    let mut game_is_going: bool = true;
    let mut turn: bool = true;

    /* Board initialization*/
    //shuffle both decks
    //TODO: shuffle
    let mut rng = thread_rng();
    rng.shuffle(&mut player_1.deck.cards);
    rng.shuffle(&mut player_2.deck.cards);
    // draw cards for each player
    for _ in 0..6 {
        println!("drawing_cards");
        draw_card(&mut player_1);
        draw_card(&mut player_2);
    }

    let mut curr_sender = &send_1;
    let mut curr_recv = &recv_1;

    player_1.print();
    player_2.print();

    /* Start game */
    while game_is_going {
        //Define who is who
        let mut current_player;
        let mut other_player;
        if turn == true {
            current_player = &mut player_1;
            other_player = &mut player_2;
            curr_sender = &send_1;
            curr_recv = &recv_1;

        } else {
            current_player = &mut player_2;
            other_player = &mut player_1;
            curr_sender = &send_2;
            curr_recv = &recv_2;

        }
        println!("\n#### This player's turn {}", current_player.name);

        //Get a mana point
        current_player.mana += 1;

        current_player.print();
        //First the player draws a card

        draw_card(current_player);

        //Turn starts,
        //unfatigue all cards
        for i in &mut current_player.field {
            i.fatigued = false;
        }
        for i in current_player.field.clone() {
            trigger_ability(
                "on_turn_start".to_owned(),
                &i.id,
                &mut current_player,
                &mut other_player,
                &curr_sender,
                &curr_recv,
            );
        }

        let mut doing_things: bool = true;
        while doing_things {

            //Asks what the player wants to do
            //The options are "play", "attack", "look", and "help"
            let mut line = String::new();
            let stdin = io::stdin();
            stdin.lock().read_line(&mut line).expect(
                "Could not read line",
            );

            let split = line.split_whitespace();
            let split: Vec<&str> = split.collect();

            if split.is_empty() {
                println!(
                    "enter a command, valid commands are \"play\", \"attack\", \"look\", and \"help\""
                );
            } else if split[0] == "play" {
                let id: i32 = split[1].parse().unwrap();
                play_card(
                    &id,
                    &mut current_player.hand,
                    &mut current_player.field,
                    &current_player.deck,
                    &mut current_player.mana,
                );
                trigger_ability(
                    "on_play".to_owned(),
                    &id,
                    &mut current_player,
                    &mut other_player,
                    &curr_sender,
                    &curr_recv,
                );
            } else if split[0] == "attack" {
                //This should all be moved to the board section
                //Make sure enough arguments were supplied
                if split.len() < 3 {
                    println!(
                        "not enough arguments, try \"attack your_monster enemy\" to attack opponent, use 999"
                    );
                } else {
                    let attacker: i32 = split[1].parse().unwrap();
                    let target: i32 = split[2].parse().unwrap();

                    attack(&attacker, &target, &mut current_player, &mut other_player);
                }
            } else if split[0] == "attack_face" {
                let mut id: i32 = split[1].parse().unwrap();
                attack_face(
                    &mut id,
                    &mut other_player,
                    &mut current_player,
                    &curr_sender,
                    &curr_recv,
                );

            } else if split[0] == "win" {
                game_is_going = false;
                break;
            } else if split[0] == "look" {
                current_player.print();
                println!("\n");
            } else if split[0] == "end" {
                doing_things = false;
            } else {
                println!(
                    "enter a command, valid commands are \"play\", \"attack\", \"look\", and \"help\""
                );
            }

        }

        for i in current_player.field.clone() {
            trigger_ability(
                "on_turn_start".to_owned(),
                &i.id,
                &mut current_player,
                &mut other_player,
                &curr_sender,
                &curr_recv,
            );
        }

        if turn == false {
            turn = true;
        } else {
            turn = false;
        }
    }

    player_1.de_init();
    player_2.de_init();
    println!("Game is over");

}
<|endoftext|>


<commit_before>//! Unix-specific extensions to primitives in the `std::process` module.

#![stable(feature = "rust1", since = "1.0.0")]

use crate::ffi::OsStr;
use crate::io;
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::process;
use crate::sealed::Sealed;
use crate::sys;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};

/// Unix-specific extensions to the [`process::Command`] builder.
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait CommandExt: Sealed {
    /// Sets the child process's user ID. This translates to a
    /// `setuid` call in the child process. Failure in the `setuid`
    /// call will cause the spawn to fail.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn uid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command;

    /// Similar to `uid`, but sets the group ID of the child process. This has
    /// the same semantics as the `uid` field.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn gid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command;

    /// Sets the supplementary group IDs for the calling process. Translates to
    /// a `setgroups` call in the child process.
    #[unstable(feature = "setgroups", issue = "38527", reason = "")]
    fn groups(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] groups: &[u32],
        #[cfg(target_os = "vxworks")] groups: &[u16],
    ) -> &mut process::Command;

    /// Schedules a closure to be run just before the `exec` function is
    /// invoked.
    ///
    /// The closure is allowed to return an I/O error whose OS error code will
    /// be communicated back to the parent and returned as an error from when
    /// the spawn was requested.
    ///
    /// Multiple closures can be registered and they will be called in order of
    /// their registration. If a closure returns `Err` then no further closures
    /// will be called and the spawn operation will immediately return with a
    /// failure.
    ///
    /// # Notes and Safety
    ///
    /// This closure will be run in the context of the child process after a
    /// `fork`. This primarily means that any modifications made to memory on
    /// behalf of this closure will **not** be visible to the parent process.
    /// This is often a very constrained environment where normal operations
    /// like `malloc`, accessing environment variables through [`std::env`]
    /// or acquiring a mutex are not guaranteed to work (due to
    /// other threads perhaps still running when the `fork` was run).
    ///
    /// For further details refer to the [POSIX fork() specification]
    /// and the equivalent documentation for any targeted
    /// platform, especially the requirements around *async-signal-safety*.
    ///
    /// This also means that all resources such as file descriptors and
    /// memory-mapped regions got duplicated. It is your responsibility to make
    /// sure that the closure does not violate library invariants by making
    /// invalid use of these duplicates.
    ///
    /// When this closure is run, aspects such as the stdio file descriptors and
    /// working directory have successfully been changed, so output to these
    /// locations may not appear where intended.
    ///
    /// [POSIX fork() specification]:
    ///     https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html
    /// [`std::env`]: mod@crate::env
    #[stable(feature = "process_pre_exec", since = "1.34.0")]
    unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
    where
        F: FnMut() -> io::Result<()> + Send + Sync + 'static;

    /// Schedules a closure to be run just before the `exec` function is
    /// invoked.
    ///
    /// This method is stable and usable, but it should be unsafe. To fix
    /// that, it got deprecated in favor of the unsafe [`pre_exec`].
    ///
    /// [`pre_exec`]: CommandExt::pre_exec
    #[stable(feature = "process_exec", since = "1.15.0")]
    #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
    fn before_exec<F>(&mut self, f: F) -> &mut process::Command
    where
        F: FnMut() -> io::Result<()> + Send + Sync + 'static,
    {
        unsafe { self.pre_exec(f) }
    }

    /// Performs all the required setup by this `Command`, followed by calling
    /// the `execvp` syscall.
    ///
    /// On success this function will not return, and otherwise it will return
    /// an error indicating why the exec (or another part of the setup of the
    /// `Command`) failed.
    ///
    /// `exec` not returning has the same implications as calling
    /// [`process::exit`] – no destructors on the current stack or any other
    /// thread’s stack will be run. Therefore, it is recommended to only call
    /// `exec` at a point where it is fine to not run any destructors. Note,
    /// that the `execvp` syscall independently guarantees that all memory is
    /// freed and all file descriptors with the `CLOEXEC` option (set by default
    /// on all file descriptors opened by the standard library) are closed.
    ///
    /// This function, unlike `spawn`, will **not** `fork` the process to create
    /// a new child. Like spawn, however, the default behavior for the stdio
    /// descriptors will be to inherited from the current process.
    ///
    /// # Notes
    ///
    /// The process may be in a "broken state" if this function returns in
    /// error. For example the working directory, environment variables, signal
    /// handling settings, various user/group information, or aspects of stdio
    /// file descriptors may have changed. If a "transactional spawn" is
    /// required to gracefully handle errors it is recommended to use the
    /// cross-platform `spawn` instead.
    #[stable(feature = "process_exec2", since = "1.9.0")]
    fn exec(&mut self) -> io::Error;

    /// Set executable argument
    ///
    /// Set the first process argument, `argv[0]`, to something other than the
    /// default executable path.
    #[stable(feature = "process_set_argv0", since = "1.45.0")]
    fn arg0<S>(&mut self, arg: S) -> &mut process::Command
    where
        S: AsRef<OsStr>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl CommandExt for process::Command {
    fn uid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command {
        self.as_inner_mut().uid(id);
        self
    }

    fn gid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command {
        self.as_inner_mut().gid(id);
        self
    }

    fn groups(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] groups: &[u32],
        #[cfg(target_os = "vxworks")] groups: &[u16],
    ) -> &mut process::Command {
        self.as_inner_mut().groups(groups);
        self
    }

    unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
    where
        F: FnMut() -> io::Result<()> + Send + Sync + 'static,
    {
        self.as_inner_mut().pre_exec(Box::new(f));
        self
    }

    fn exec(&mut self) -> io::Error {
        // NOTE: This may *not* be safe to call after `libc::fork`, because it
        // may allocate. That may be worth fixing at some point in the future.
        self.as_inner_mut().exec(sys::process::Stdio::Inherit)
    }

    fn arg0<S>(&mut self, arg: S) -> &mut process::Command
    where
        S: AsRef<OsStr>,
    {
        self.as_inner_mut().set_arg_0(arg.as_ref());
        self
    }
}

/// Unix-specific extensions to [`process::ExitStatus`].
///
/// On Unix, `ExitStatus` **does not necessarily represent an exit status**, as passed to the
/// `exit` system call or returned by [`ExitStatus::code()`](crate::process::ExitStatus::code).
/// It represents **any wait status**, as returned by one of the `wait` family of system calls.
///
/// This is because a Unix wait status (a Rust `ExitStatus`) can represent a Unix exit status, but
/// can also represent other kinds of process event.
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ExitStatusExt: Sealed {
    /// Creates a new `ExitStatus` from the raw underlying integer status value from `wait`
    ///
    /// The value should be a **wait status, not an exit status**.
    #[stable(feature = "exit_status_from", since = "1.12.0")]
    fn from_raw(raw: i32) -> Self;

    /// If the process was terminated by a signal, returns that signal.
    ///
    /// In other words, if `WIFSIGNALED`, this returns `WTERMSIG`.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn signal(&self) -> Option<i32>;

    /// If the process was terminated by a signal, says whether it dumped core.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn core_dumped(&self) -> bool;

    /// If the process was stopped by a signal, returns that signal.
    ///
    /// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`.  This is only possible if the status came from
    /// a `wait` system call which was passed `WUNTRACED`, and was then converted into an `ExitStatus`.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn stopped_signal(&self) -> Option<i32>;

    /// Whether the process was continued from a stopped status.
    ///
    /// Ie, `WIFCONTINUED`.  This is only possible if the status came from a `wait` system call
    /// which was passed `WCONTINUED`, and was then converted into an `ExitStatus`.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn continued(&self) -> bool;

    /// Returns the underlying raw `wait` status.
    ///
    /// The returned integer is a **wait status, not an exit status**.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn into_raw(self) -> i32;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ExitStatusExt for process::ExitStatus {
    fn from_raw(raw: i32) -> Self {
        process::ExitStatus::from_inner(From::from(raw))
    }

    fn signal(&self) -> Option<i32> {
        self.as_inner().signal()
    }

    fn core_dumped(&self) -> bool {
        self.as_inner().core_dumped()
    }

    fn stopped_signal(&self) -> Option<i32> {
        self.as_inner().stopped_signal()
    }

    fn continued(&self) -> bool {
        self.as_inner().continued()
    }

    fn into_raw(self) -> i32 {
        self.as_inner().into_raw().into()
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl FromRawFd for process::Stdio {
    #[inline]
    unsafe fn from_raw_fd(fd: RawFd) -> process::Stdio {
        let fd = sys::fd::FileDesc::new(fd);
        let io = sys::process::Stdio::Fd(fd);
        process::Stdio::from_inner(io)
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl AsRawFd for process::ChildStdin {
    #[inline]
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl AsRawFd for process::ChildStdout {
    #[inline]
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl AsRawFd for process::ChildStderr {
    #[inline]
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for process::ChildStdin {
    #[inline]
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for process::ChildStdout {
    #[inline]
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for process::ChildStderr {
    #[inline]
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

/// Returns the OS-assigned process identifier associated with this process's parent.
#[stable(feature = "unix_ppid", since = "1.27.0")]
pub fn parent_id() -> u32 {
    crate::sys::os::getppid()
}
<commit_msg>unix process: pre_exec: Discuss panic safety<commit_after>//! Unix-specific extensions to primitives in the `std::process` module.

#![stable(feature = "rust1", since = "1.0.0")]

use crate::ffi::OsStr;
use crate::io;
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::process;
use crate::sealed::Sealed;
use crate::sys;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};

/// Unix-specific extensions to the [`process::Command`] builder.
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait CommandExt: Sealed {
    /// Sets the child process's user ID. This translates to a
    /// `setuid` call in the child process. Failure in the `setuid`
    /// call will cause the spawn to fail.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn uid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command;

    /// Similar to `uid`, but sets the group ID of the child process. This has
    /// the same semantics as the `uid` field.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn gid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command;

    /// Sets the supplementary group IDs for the calling process. Translates to
    /// a `setgroups` call in the child process.
    #[unstable(feature = "setgroups", issue = "38527", reason = "")]
    fn groups(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] groups: &[u32],
        #[cfg(target_os = "vxworks")] groups: &[u16],
    ) -> &mut process::Command;

    /// Schedules a closure to be run just before the `exec` function is
    /// invoked.
    ///
    /// The closure is allowed to return an I/O error whose OS error code will
    /// be communicated back to the parent and returned as an error from when
    /// the spawn was requested.
    ///
    /// Multiple closures can be registered and they will be called in order of
    /// their registration. If a closure returns `Err` then no further closures
    /// will be called and the spawn operation will immediately return with a
    /// failure.
    ///
    /// # Notes and Safety
    ///
    /// This closure will be run in the context of the child process after a
    /// `fork`. This primarily means that any modifications made to memory on
    /// behalf of this closure will **not** be visible to the parent process.
    /// This is often a very constrained environment where normal operations
    /// like `malloc`, accessing environment variables through [`std::env`]
    /// or acquiring a mutex are not guaranteed to work (due to
    /// other threads perhaps still running when the `fork` was run).
    ///
    /// For further details refer to the [POSIX fork() specification]
    /// and the equivalent documentation for any targeted
    /// platform, especially the requirements around *async-signal-safety*.
    ///
    /// This also means that all resources such as file descriptors and
    /// memory-mapped regions got duplicated. It is your responsibility to make
    /// sure that the closure does not violate library invariants by making
    /// invalid use of these duplicates.
    ///
    /// Panicking in the closure is safe only if all the format arguments for the
    /// panic message can be safely formatted; this is because although
    /// `Command` calls [`std::panic::always_abort`](crate::panic::always_abort)
    /// before calling the pre_exec hook, panic will still try to format the
    /// panic message.
    ///
    /// When this closure is run, aspects such as the stdio file descriptors and
    /// working directory have successfully been changed, so output to these
    /// locations may not appear where intended.
    ///
    /// [POSIX fork() specification]:
    ///     https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html
    /// [`std::env`]: mod@crate::env
    #[stable(feature = "process_pre_exec", since = "1.34.0")]
    unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
    where
        F: FnMut() -> io::Result<()> + Send + Sync + 'static;

    /// Schedules a closure to be run just before the `exec` function is
    /// invoked.
    ///
    /// This method is stable and usable, but it should be unsafe. To fix
    /// that, it got deprecated in favor of the unsafe [`pre_exec`].
    ///
    /// [`pre_exec`]: CommandExt::pre_exec
    #[stable(feature = "process_exec", since = "1.15.0")]
    #[rustc_deprecated(since = "1.37.0", reason = "should be unsafe, use `pre_exec` instead")]
    fn before_exec<F>(&mut self, f: F) -> &mut process::Command
    where
        F: FnMut() -> io::Result<()> + Send + Sync + 'static,
    {
        unsafe { self.pre_exec(f) }
    }

    /// Performs all the required setup by this `Command`, followed by calling
    /// the `execvp` syscall.
    ///
    /// On success this function will not return, and otherwise it will return
    /// an error indicating why the exec (or another part of the setup of the
    /// `Command`) failed.
    ///
    /// `exec` not returning has the same implications as calling
    /// [`process::exit`] – no destructors on the current stack or any other
    /// thread’s stack will be run. Therefore, it is recommended to only call
    /// `exec` at a point where it is fine to not run any destructors. Note,
    /// that the `execvp` syscall independently guarantees that all memory is
    /// freed and all file descriptors with the `CLOEXEC` option (set by default
    /// on all file descriptors opened by the standard library) are closed.
    ///
    /// This function, unlike `spawn`, will **not** `fork` the process to create
    /// a new child. Like spawn, however, the default behavior for the stdio
    /// descriptors will be to inherited from the current process.
    ///
    /// # Notes
    ///
    /// The process may be in a "broken state" if this function returns in
    /// error. For example the working directory, environment variables, signal
    /// handling settings, various user/group information, or aspects of stdio
    /// file descriptors may have changed. If a "transactional spawn" is
    /// required to gracefully handle errors it is recommended to use the
    /// cross-platform `spawn` instead.
    #[stable(feature = "process_exec2", since = "1.9.0")]
    fn exec(&mut self) -> io::Error;

    /// Set executable argument
    ///
    /// Set the first process argument, `argv[0]`, to something other than the
    /// default executable path.
    #[stable(feature = "process_set_argv0", since = "1.45.0")]
    fn arg0<S>(&mut self, arg: S) -> &mut process::Command
    where
        S: AsRef<OsStr>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl CommandExt for process::Command {
    fn uid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command {
        self.as_inner_mut().uid(id);
        self
    }

    fn gid(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] id: u32,
        #[cfg(target_os = "vxworks")] id: u16,
    ) -> &mut process::Command {
        self.as_inner_mut().gid(id);
        self
    }

    fn groups(
        &mut self,
        #[cfg(not(target_os = "vxworks"))] groups: &[u32],
        #[cfg(target_os = "vxworks")] groups: &[u16],
    ) -> &mut process::Command {
        self.as_inner_mut().groups(groups);
        self
    }

    unsafe fn pre_exec<F>(&mut self, f: F) -> &mut process::Command
    where
        F: FnMut() -> io::Result<()> + Send + Sync + 'static,
    {
        self.as_inner_mut().pre_exec(Box::new(f));
        self
    }

    fn exec(&mut self) -> io::Error {
        // NOTE: This may *not* be safe to call after `libc::fork`, because it
        // may allocate. That may be worth fixing at some point in the future.
        self.as_inner_mut().exec(sys::process::Stdio::Inherit)
    }

    fn arg0<S>(&mut self, arg: S) -> &mut process::Command
    where
        S: AsRef<OsStr>,
    {
        self.as_inner_mut().set_arg_0(arg.as_ref());
        self
    }
}

/// Unix-specific extensions to [`process::ExitStatus`].
///
/// On Unix, `ExitStatus` **does not necessarily represent an exit status**, as passed to the
/// `exit` system call or returned by [`ExitStatus::code()`](crate::process::ExitStatus::code).
/// It represents **any wait status**, as returned by one of the `wait` family of system calls.
///
/// This is because a Unix wait status (a Rust `ExitStatus`) can represent a Unix exit status, but
/// can also represent other kinds of process event.
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ExitStatusExt: Sealed {
    /// Creates a new `ExitStatus` from the raw underlying integer status value from `wait`
    ///
    /// The value should be a **wait status, not an exit status**.
    #[stable(feature = "exit_status_from", since = "1.12.0")]
    fn from_raw(raw: i32) -> Self;

    /// If the process was terminated by a signal, returns that signal.
    ///
    /// In other words, if `WIFSIGNALED`, this returns `WTERMSIG`.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn signal(&self) -> Option<i32>;

    /// If the process was terminated by a signal, says whether it dumped core.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn core_dumped(&self) -> bool;

    /// If the process was stopped by a signal, returns that signal.
    ///
    /// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`.  This is only possible if the status came from
    /// a `wait` system call which was passed `WUNTRACED`, and was then converted into an `ExitStatus`.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn stopped_signal(&self) -> Option<i32>;

    /// Whether the process was continued from a stopped status.
    ///
    /// Ie, `WIFCONTINUED`.  This is only possible if the status came from a `wait` system call
    /// which was passed `WCONTINUED`, and was then converted into an `ExitStatus`.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn continued(&self) -> bool;

    /// Returns the underlying raw `wait` status.
    ///
    /// The returned integer is a **wait status, not an exit status**.
    #[unstable(feature = "unix_process_wait_more", issue = "80695")]
    fn into_raw(self) -> i32;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ExitStatusExt for process::ExitStatus {
    fn from_raw(raw: i32) -> Self {
        process::ExitStatus::from_inner(From::from(raw))
    }

    fn signal(&self) -> Option<i32> {
        self.as_inner().signal()
    }

    fn core_dumped(&self) -> bool {
        self.as_inner().core_dumped()
    }

    fn stopped_signal(&self) -> Option<i32> {
        self.as_inner().stopped_signal()
    }

    fn continued(&self) -> bool {
        self.as_inner().continued()
    }

    fn into_raw(self) -> i32 {
        self.as_inner().into_raw().into()
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl FromRawFd for process::Stdio {
    #[inline]
    unsafe fn from_raw_fd(fd: RawFd) -> process::Stdio {
        let fd = sys::fd::FileDesc::new(fd);
        let io = sys::process::Stdio::Fd(fd);
        process::Stdio::from_inner(io)
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl AsRawFd for process::ChildStdin {
    #[inline]
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl AsRawFd for process::ChildStdout {
    #[inline]
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl AsRawFd for process::ChildStderr {
    #[inline]
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for process::ChildStdin {
    #[inline]
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for process::ChildStdout {
    #[inline]
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for process::ChildStderr {
    #[inline]
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

/// Returns the OS-assigned process identifier associated with this process's parent.
#[stable(feature = "unix_ppid", since = "1.27.0")]
pub fn parent_id() -> u32 {
    crate::sys::os::getppid()
}
<|endoftext|>


<commit_before>use std::cmp::PartialOrd;
use num::{Num, Signed, Zero, One, abs};
use Anchor;

#[derive(Copy, Clone, PartialEq, PartialOrd, Hash, Default, Debug, Serialize, Deserialize)]
pub struct Rect<T: Copy> {
    /// Top left (closest to the origin) corner of the rectange.
    pub top: [T; 2],
    /// Size of the rectangle, all elements are assumed to always be positive.
    pub size: [T; 2],
}

impl<T> Rect<T> where T: Num + PartialOrd + Signed + Copy
{
    /// Create a new rectangle from two corner points.
    pub fn new<V: Into<[T; 2]>>(p1: V, p2: V) -> Rect<T> {
        let (p1, p2): ([T; 2], [T; 2]) = (p1.into(), p2.into());

        Rect {
            top: [*min(&p1[0], &p2[0]), *min(&p1[1], &p2[1])],
            size: [abs(p2[0] - p1[0]), abs(p2[1] - p1[1])],
        }
    }

    pub fn point(&self, point: Anchor) -> [T; 2] {
        let one: T = One::one();
        let two = one + one;
        match point {
            Anchor::TopLeft => self.top,
            Anchor::TopRight => [self.top[0] + self.size[0], self.top[1]],
            Anchor::BottomLeft => [self.top[0], self.top[1] + self.size[1]],
            Anchor::BottomRight => {
                [self.top[0] + self.size[0], self.top[1] + self.size[1]]
            }
            Anchor::Top => [self.top[0] + self.size[0] / two, self.top[1]],
            Anchor::Left => [self.top[0], self.top[1] + self.size[1] / two],
            Anchor::Right => {
                [self.top[0] + self.size[0], self.top[1] + self.size[1] / two]
            }
            Anchor::Bottom => {
                [self.top[0] + self.size[0] / two, self.top[1] + self.size[1]]
            }
            Anchor::Center => {
                [self.top[0] + self.size[0] / two,
                 self.top[1] + self.size[1] / two]
            }
        }
    }

    /// Iterate tiles of the given size inside the rectangle.
    ///
    /// The tiles are ordered from left to right, then from top to bottom. The
    /// first tile snaps to the top left corner of the rectangle, and parts
    /// along the right and bottom edges of the rectangle are left uncovered
    /// if a whole tile will not fit in them.
    ///
    /// ```
    /// use calx_layout::Rect;
    ///
    /// let x = Rect::new([0, 0], [8, 16]);
    /// // To iterate integer points in the rectangle, just use [1, 1] tiles.
    /// assert_eq!(x.tiles([1, 1]).map(|x| x.top).next(), Some([0, 0]));
    /// assert_eq!(x.tiles([1, 1]).count(), 8 * 16);
    ///
    /// let y = Rect::new([0.0, 0.0], [3.141, 2.718]);
    /// assert_eq!(y.tiles([1.0, 1.0]).count(), 3 * 2);
    /// ```
    pub fn tiles<'a, V: Into<[T; 2]>>(&'a self, dim: V) -> TileIter<'a, T> {
        TileIter::new(self, dim.into())
    }

    pub fn area(&self) -> T {
        self.size[0] * self.size[1]
    }
}

/// Iterator for packed left-to-right top-to-bottom subrectangles
pub struct TileIter<'a, T: 'a + Copy> {
    base: &'a Rect<T>,
    dim: [T; 2],
    x: T,
    y: T,
}

impl<'a, T: Num + PartialOrd + Copy + 'a> TileIter<'a, T> {
    fn new(base: &'a Rect<T>, dim: [T; 2]) -> TileIter<T> {
        assert!(dim[0] > Zero::zero() && dim[1] > Zero::zero());
        TileIter {
            base: base,
            dim: dim,
            x: Zero::zero(),
            y: Zero::zero(),
        }
    }
}

impl<'a, T: Num + PartialOrd + Copy> Iterator for TileIter<'a, T> {
    type Item = Rect<T>;

    fn next(&mut self) -> Option<Rect<T>> {
        if self.dim[0] > self.base.size[0] {
            return None;
        }

        if (self.x + One::one()) * self.dim[0] > self.base.size[0] {
            self.y = self.y + One::one();
            self.x = Zero::zero();
        }

        if (self.y + One::one()) * self.dim[1] > self.base.size[1] {
            return None;
        }

        let ret = Rect {
            top: [self.x * self.dim[0], self.y * self.dim[1]],
            size: self.dim,
        };
        self.x = self.x + One::one();
        Some(ret)
    }
}

fn min<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> &'a T {
    if a.lt(b) {
        a
    } else {
        b
    }
}
<commit_msg>Rectangle merge<commit_after>use std::cmp::PartialOrd;
use num::{Num, Signed, Zero, One, abs};
use Anchor;

#[derive(Copy, Clone, PartialEq, PartialOrd, Hash, Default, Debug, Serialize, Deserialize)]
pub struct Rect<T: Copy> {
    /// Top left (closest to the origin) corner of the rectange.
    pub top: [T; 2],
    /// Size of the rectangle, all elements are assumed to always be positive.
    pub size: [T; 2],
}

impl<T> Rect<T> where T: Num + PartialOrd + Signed + Copy
{
    /// Create a new rectangle from two corner points.
    pub fn new<V: Into<[T; 2]>>(p1: V, p2: V) -> Rect<T> {
        let (p1, p2): ([T; 2], [T; 2]) = (p1.into(), p2.into());

        Rect {
            top: [*min(&p1[0], &p2[0]), *min(&p1[1], &p2[1])],
            size: [abs(p2[0] - p1[0]), abs(p2[1] - p1[1])],
        }
    }

    pub fn point(&self, point: Anchor) -> [T; 2] {
        let one: T = One::one();
        let two = one + one;
        match point {
            Anchor::TopLeft => self.top,
            Anchor::TopRight => [self.top[0] + self.size[0], self.top[1]],
            Anchor::BottomLeft => [self.top[0], self.top[1] + self.size[1]],
            Anchor::BottomRight => {
                [self.top[0] + self.size[0], self.top[1] + self.size[1]]
            }
            Anchor::Top => [self.top[0] + self.size[0] / two, self.top[1]],
            Anchor::Left => [self.top[0], self.top[1] + self.size[1] / two],
            Anchor::Right => {
                [self.top[0] + self.size[0], self.top[1] + self.size[1] / two]
            }
            Anchor::Bottom => {
                [self.top[0] + self.size[0] / two, self.top[1] + self.size[1]]
            }
            Anchor::Center => {
                [self.top[0] + self.size[0] / two,
                 self.top[1] + self.size[1] / two]
            }
        }
    }

    /// Iterate tiles of the given size inside the rectangle.
    ///
    /// The tiles are ordered from left to right, then from top to bottom. The
    /// first tile snaps to the top left corner of the rectangle, and parts
    /// along the right and bottom edges of the rectangle are left uncovered
    /// if a whole tile will not fit in them.
    ///
    /// ```
    /// use calx_layout::Rect;
    ///
    /// let x = Rect::new([0, 0], [8, 16]);
    /// // To iterate integer points in the rectangle, just use [1, 1] tiles.
    /// assert_eq!(x.tiles([1, 1]).map(|x| x.top).next(), Some([0, 0]));
    /// assert_eq!(x.tiles([1, 1]).count(), 8 * 16);
    ///
    /// let y = Rect::new([0.0, 0.0], [3.141, 2.718]);
    /// assert_eq!(y.tiles([1.0, 1.0]).count(), 3 * 2);
    /// ```
    pub fn tiles<'a, V: Into<[T; 2]>>(&'a self, dim: V) -> TileIter<'a, T> {
        TileIter::new(self, dim.into())
    }

    pub fn area(&self) -> T {
        self.size[0] * self.size[1]
    }

    /// Produce the smallest new rectangle that contains both input
    /// rectangles.
    pub fn merge(&self, other: &Rect<T>) -> Rect<T> {
        Rect {
            top: [*min(&self.top[0], &other.top[0]), *min(&self.top[1], &other.top[1])],
            size: [*max(&self.size[0], &other.size[0]), *max(&self.size[1], &other.size[1])]
        }

    }
}

/// Iterator for packed left-to-right top-to-bottom subrectangles
pub struct TileIter<'a, T: 'a + Copy> {
    base: &'a Rect<T>,
    dim: [T; 2],
    x: T,
    y: T,
}

impl<'a, T: Num + PartialOrd + Copy + 'a> TileIter<'a, T> {
    fn new(base: &'a Rect<T>, dim: [T; 2]) -> TileIter<T> {
        assert!(dim[0] > Zero::zero() && dim[1] > Zero::zero());
        TileIter {
            base: base,
            dim: dim,
            x: Zero::zero(),
            y: Zero::zero(),
        }
    }
}

impl<'a, T: Num + PartialOrd + Copy> Iterator for TileIter<'a, T> {
    type Item = Rect<T>;

    fn next(&mut self) -> Option<Rect<T>> {
        if self.dim[0] > self.base.size[0] {
            return None;
        }

        if (self.x + One::one()) * self.dim[0] > self.base.size[0] {
            self.y = self.y + One::one();
            self.x = Zero::zero();
        }

        if (self.y + One::one()) * self.dim[1] > self.base.size[1] {
            return None;
        }

        let ret = Rect {
            top: [self.x * self.dim[0], self.y * self.dim[1]],
            size: self.dim,
        };
        self.x = self.x + One::one();
        Some(ret)
    }
}

fn min<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> &'a T {
    if a.lt(b) {
        a
    } else {
        b
    }
}

fn max<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> &'a T {
    if a.gt(b) {
        a
    } else {
        b
    }
}
<|endoftext|>


<commit_before>#![feature(trace_macros)]
#![recursion_limit = "128"]
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;

// trace_macros!(true);

custom_derive! {
    #[derive(Copy, Clone, Eq, PartialEq, Debug,
        NewtypeAdd, NewtypeAdd(&self), NewtypeAdd(i32), NewtypeAdd(&self, i32),
        NewtypeBitAnd, NewtypeBitAnd(&self),
        NewtypeBitOr, NewtypeBitOr(&self),
        NewtypeBitXor, NewtypeBitXor(&self),
        NewtypeDiv, NewtypeDiv(&self),
        NewtypeMul, NewtypeMul(&self),
        NewtypeRem, NewtypeRem(&self),
        NewtypeSub, NewtypeSub(&self),

        NewtypeShl(), NewtypeShl(&self), NewtypeShl(usize), NewtypeShl(&self, usize),
        NewtypeShr(), NewtypeShr(&self), NewtypeShr(usize), NewtypeShr(&self, usize),

        NewtypeNeg, NewtypeNeg(&self),
        NewtypeNot, NewtypeNot(ref),

        NewtypeFrom
        )]
    pub struct Dummy(i32);
}

#[test]
fn test_arith() {
    let a = Dummy::from(4);
    let b = Dummy::from(7);

    assert_eq!(a + b, Dummy::from(4 + 7));
    assert_eq!(&a + &b, Dummy::from(4 + 7));
    assert_eq!(a + 7, Dummy::from(4 + 7));
    assert_eq!(&a + 7, Dummy::from(4 + 7));
    assert_eq!(a & b, Dummy::from(4 & 7));
    assert_eq!(&a & &b, Dummy::from(4 & 7));
    assert_eq!(a | b, Dummy::from(4 | 7));
    assert_eq!(&a | &b, Dummy::from(4 | 7));
    assert_eq!(a ^ b, Dummy::from(4 ^ 7));
    assert_eq!(&a ^ &b, Dummy::from(4 ^ 7));
    assert_eq!(a / b, Dummy::from(4 / 7));
    assert_eq!(&a / &b, Dummy::from(4 / 7));
    assert_eq!(a * b, Dummy::from(4 * 7));
    assert_eq!(&a * &b, Dummy::from(4 * 7));
    assert_eq!(a % b, Dummy::from(4 % 7));
    assert_eq!(&a % &b, Dummy::from(4 % 7));
    assert_eq!(a - b, Dummy::from(4 - 7));
    assert_eq!(&a - &b, Dummy::from(4 - 7));

    assert_eq!(a << b, Dummy::from(4 << 7));
    assert_eq!(&a << &b, Dummy::from(4 << 7));
    assert_eq!(a << 7, Dummy::from(4 << 7));

    assert_eq!(a >> b, Dummy::from(4 >> 7));
    assert_eq!(&a >> &b, Dummy::from(4 >> 7));
    assert_eq!(a >> 7, Dummy::from(4 >> 7));

    assert_eq!(-a, Dummy::from(-4));
    assert_eq!(-&a, Dummy::from(-4));
    assert_eq!(!a, Dummy::from(!4));
    assert_eq!(!&a, Dummy::from(!4));
}
<commit_msg>Fixed broken arith test.<commit_after>#![feature(trace_macros)]
#![recursion_limit = "128"]
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;

// trace_macros!(true);

custom_derive! {
    #[derive(Copy, Clone, Eq, PartialEq, Debug,
        NewtypeAdd, NewtypeAdd(&self), NewtypeAdd(i32), NewtypeAdd(&self, i32),
        NewtypeBitAnd, NewtypeBitAnd(&self),
        NewtypeBitOr, NewtypeBitOr(&self),
        NewtypeBitXor, NewtypeBitXor(&self),
        NewtypeDiv, NewtypeDiv(&self),
        NewtypeMul, NewtypeMul(&self),
        NewtypeRem, NewtypeRem(&self),
        NewtypeSub, NewtypeSub(&self),

        NewtypeShl(), NewtypeShl(&self), NewtypeShl(usize), NewtypeShl(&self, usize),
        NewtypeShr(), NewtypeShr(&self), NewtypeShr(usize), NewtypeShr(&self, usize),

        NewtypeNeg, NewtypeNeg(&self),
        NewtypeNot, NewtypeNot(&self),

        NewtypeFrom
        )]
    pub struct Dummy(i32);
}

#[test]
fn test_arith() {
    let a = Dummy::from(4);
    let b = Dummy::from(7);

    assert_eq!(a + b, Dummy::from(4 + 7));
    assert_eq!(&a + &b, Dummy::from(4 + 7));
    assert_eq!(a + 7, Dummy::from(4 + 7));
    assert_eq!(&a + 7, Dummy::from(4 + 7));
    assert_eq!(a & b, Dummy::from(4 & 7));
    assert_eq!(&a & &b, Dummy::from(4 & 7));
    assert_eq!(a | b, Dummy::from(4 | 7));
    assert_eq!(&a | &b, Dummy::from(4 | 7));
    assert_eq!(a ^ b, Dummy::from(4 ^ 7));
    assert_eq!(&a ^ &b, Dummy::from(4 ^ 7));
    assert_eq!(a / b, Dummy::from(4 / 7));
    assert_eq!(&a / &b, Dummy::from(4 / 7));
    assert_eq!(a * b, Dummy::from(4 * 7));
    assert_eq!(&a * &b, Dummy::from(4 * 7));
    assert_eq!(a % b, Dummy::from(4 % 7));
    assert_eq!(&a % &b, Dummy::from(4 % 7));
    assert_eq!(a - b, Dummy::from(4 - 7));
    assert_eq!(&a - &b, Dummy::from(4 - 7));

    assert_eq!(a << b, Dummy::from(4 << 7));
    assert_eq!(&a << &b, Dummy::from(4 << 7));
    assert_eq!(a << 7, Dummy::from(4 << 7));

    assert_eq!(a >> b, Dummy::from(4 >> 7));
    assert_eq!(&a >> &b, Dummy::from(4 >> 7));
    assert_eq!(a >> 7, Dummy::from(4 >> 7));

    assert_eq!(-a, Dummy::from(-4));
    assert_eq!(-&a, Dummy::from(-4));
    assert_eq!(!a, Dummy::from(!4));
    assert_eq!(!&a, Dummy::from(!4));
}
<|endoftext|>