<commit_before>//! Renderer for `const` fields.

use hir::{AsAssocItem, HasSource};
use ide_db::SymbolKind;
use syntax::{ast::Const, display::const_label};

use crate::{item::CompletionItem, render::RenderContext};

pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
    let _p = profile::span("render_const");
    ConstRender::new(ctx, const_)?.render()
}

#[derive(Debug)]
struct ConstRender<'a> {
    ctx: RenderContext<'a>,
    const_: hir::Const,
    ast_node: Const,
}

impl<'a> ConstRender<'a> {
    fn new(ctx: RenderContext<'a>, const_: hir::Const) -> Option<ConstRender<'a>> {
        let ast_node = const_.source(ctx.db())?.value;
        Some(ConstRender { ctx, const_, ast_node })
    }

    fn render(self) -> Option<CompletionItem> {
        let name = self.const_.name(self.ctx.db())?.to_smol_str();
        let detail = self.detail();

        let mut item =
            CompletionItem::new(SymbolKind::Const, self.ctx.source_range(), name.clone());
        item.set_documentation(self.ctx.docs(self.const_))
            .set_deprecated(
                self.ctx.is_deprecated(self.const_)
                    || self.ctx.is_deprecated_assoc_item(self.const_),
            )
            .detail(detail);

        let db = self.ctx.db();
        if let Some(actm) = self.const_.as_assoc_item(db) {
            if let Some(trt) = actm.containing_trait_or_trait_impl(db) {
                item.trait_name(trt.name(db).to_smol_str());
                item.insert_text(name);
            }
        }

        Some(item.build())
    }

    fn detail(&self) -> String {
        const_label(&self.ast_node)
    }
}
<commit_msg>Simplify const rendering, remove constructor structs<commit_after>//! Renderer for `const` fields.

use hir::{AsAssocItem, HasSource};
use ide_db::SymbolKind;
use syntax::display::const_label;

use crate::{item::CompletionItem, render::RenderContext};

pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
    let _p = profile::span("render_const");
    render(ctx, const_)
}

fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
    let db = ctx.db();
    let name = const_.name(db)?.to_smol_str();
    // FIXME: This is parsing files!
    let detail = const_label(&const_.source(db)?.value);

    let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), name.clone());
    item.set_documentation(ctx.docs(const_))
        .set_deprecated(ctx.is_deprecated(const_) || ctx.is_deprecated_assoc_item(const_))
        .detail(detail);

    if let Some(actm) = const_.as_assoc_item(db) {
        if let Some(trt) = actm.containing_trait_or_trait_impl(db) {
            item.trait_name(trt.name(db).to_smol_str());
            item.insert_text(name);
        }
    }

    Some(item.build())
}
<|endoftext|>


<commit_before>//! Endpoints for client devices to exchange information not persisted in room DAG.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

use ruma_identifiers::DeviceIdBox;
use serde::{
    de::{self, Unexpected},
    Deserialize, Deserializer, Serialize, Serializer,
};

pub mod send_event_to_device;

/// Represents one or all of a user's devices.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum DeviceIdOrAllDevices {
    /// Represents a device Id for one of a user's devices.
    DeviceId(DeviceIdBox),

    /// Represents all devices for a user.
    AllDevices,
}

impl Display for DeviceIdOrAllDevices {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        match self {
            DeviceIdOrAllDevices::DeviceId(device_id) => write!(f, "{}", device_id.to_string()),
            DeviceIdOrAllDevices::AllDevices => write!(f, "*"),
        }
    }
}

impl TryFrom<&str> for DeviceIdOrAllDevices {
    type Error = &'static str;
    fn try_from(device_id_or_all_devices: &str) -> Result<Self, Self::Error> {
        if device_id_or_all_devices.is_empty() {
            Err("Device identifier cannot be empty")
        } else if "*" == device_id_or_all_devices {
            Ok(DeviceIdOrAllDevices::AllDevices)
        } else {
            Ok(DeviceIdOrAllDevices::DeviceId(device_id_or_all_devices.into()))
        }
    }
}

impl Serialize for DeviceIdOrAllDevices {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            Self::DeviceId(device_id) => device_id.serialize(serializer),
            Self::AllDevices => serializer.serialize_str("*"),
        }
    }
}

impl<'de> Deserialize<'de> for DeviceIdOrAllDevices {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = ruma_serde::deserialize_cow_str(deserializer)?;
        DeviceIdOrAllDevices::try_from(s.as_ref()).map_err(|_| {
            de::Error::invalid_value(Unexpected::Str(&s), &"a valid device identifier or '*'")
        })
    }
}
<commit_msg>client-api: Allow the DeviceId to turn into a DeviceIdOrAllDevices<commit_after>//! Endpoints for client devices to exchange information not persisted in room DAG.

use std::{
    convert::TryFrom,
    fmt::{Display, Formatter, Result as FmtResult},
};

use ruma_identifiers::DeviceIdBox;
use serde::{
    de::{self, Unexpected},
    Deserialize, Deserializer, Serialize, Serializer,
};

pub mod send_event_to_device;

/// Represents one or all of a user's devices.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum DeviceIdOrAllDevices {
    /// Represents a device Id for one of a user's devices.
    DeviceId(DeviceIdBox),

    /// Represents all devices for a user.
    AllDevices,
}

impl Display for DeviceIdOrAllDevices {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        match self {
            DeviceIdOrAllDevices::DeviceId(device_id) => write!(f, "{}", device_id.to_string()),
            DeviceIdOrAllDevices::AllDevices => write!(f, "*"),
        }
    }
}

impl From<DeviceIdBox> for DeviceIdOrAllDevices {
    fn from(d: DeviceIdBox) -> Self {
        DeviceIdOrAllDevices::DeviceId(d)
    }
}

impl TryFrom<&str> for DeviceIdOrAllDevices {
    type Error = &'static str;
    fn try_from(device_id_or_all_devices: &str) -> Result<Self, Self::Error> {
        if device_id_or_all_devices.is_empty() {
            Err("Device identifier cannot be empty")
        } else if "*" == device_id_or_all_devices {
            Ok(DeviceIdOrAllDevices::AllDevices)
        } else {
            Ok(DeviceIdOrAllDevices::DeviceId(device_id_or_all_devices.into()))
        }
    }
}

impl Serialize for DeviceIdOrAllDevices {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            Self::DeviceId(device_id) => device_id.serialize(serializer),
            Self::AllDevices => serializer.serialize_str("*"),
        }
    }
}

impl<'de> Deserialize<'de> for DeviceIdOrAllDevices {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = ruma_serde::deserialize_cow_str(deserializer)?;
        DeviceIdOrAllDevices::try_from(s.as_ref()).map_err(|_| {
            de::Error::invalid_value(Unexpected::Str(&s), &"a valid device identifier or '*'")
        })
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix embed_image feature<commit_after><|endoftext|>


<commit_before>#![feature(proc_macro)]

#[macro_use]
extern crate stdweb;
use stdweb::js_export;

extern crate kay;
use kay::ActorSystem;

extern crate citybound_common;
use citybound_common::*;

use std::panic;

// TODO: not thread safe for now
static mut SYSTEM: *mut ActorSystem = 0 as *mut ActorSystem;

#[js_export]
pub fn start() {
    panic::set_hook(Box::new(|info| console!(error, info.to_string())));

    js!{ console.log("Before setup") }

    let mut system = kay::ActorSystem::new(kay::Networking::new(
        1,
        vec!["localhost:9999", "ws-client"],
        50_000,
        10,
        1,
    ));
    setup_all(&mut system);

    system.networking_connect();

    let browser_ui_id = citybound_common::browser_ui::BrowserUIID::spawn(&mut system.world());

    system.process_all_messages();

    js!{ console.log("After setup") }

    let mut main_loop = MainLoop { browser_ui_id };

    unsafe { SYSTEM = Box::into_raw(Box::new(system)) };

    main_loop.frame();
}

#[derive(Copy, Clone)]
struct MainLoop {
    browser_ui_id: citybound_common::browser_ui::BrowserUIID,
}

impl MainLoop {
    fn frame(&mut self) {
        let system = unsafe { &mut *SYSTEM };
        let world = &mut system.world();

        system.process_all_messages();

        self.browser_ui_id.on_frame(world);
        system.process_all_messages();

        system.networking_send_and_receive();

        js!{
            window.cbclient.setState(oldState => update(oldState, {
                system: {networkingTurns: {"$set":
                    @{system.networking_debug_all_n_turns()}
                }
            }}));

            window.cbclient.onFrame();
        }

        system.process_all_messages();

        let maybe_sleep = system.networking_finish_turn();
        let mut next = self.clone();

        // TODO: still do a frame every frame but maybe stall just the actor system

        let next_step_in_ms = match maybe_sleep {
            None => {
                ::stdweb::web::window().request_animation_frame(move |_| next.frame());
            }
            Some(duration) => {
                let sleep_nanos = duration.subsec_nanos() as u64;
                let sleep_ms =
                    (1000 * 1000 * 1000 * duration.as_secs() + sleep_nanos) / (1000 * 1000);

                ::stdweb::web::set_timeout(
                    move || {
                        ::stdweb::web::window().request_animation_frame(move |_| next.frame());
                    },
                    sleep_ms as u32,
                );
            }
        };
    }
}

mod planning_browser;
pub use planning_browser::*;
<commit_msg>Skip network turns instead of waiting in browser<commit_after>#![feature(proc_macro)]

#[macro_use]
extern crate stdweb;
use stdweb::js_export;

extern crate kay;
use kay::ActorSystem;

extern crate citybound_common;
use citybound_common::*;

use std::panic;

// TODO: not thread safe for now
static mut SYSTEM: *mut ActorSystem = 0 as *mut ActorSystem;

#[js_export]
pub fn start() {
    panic::set_hook(Box::new(|info| console!(error, info.to_string())));

    js!{ console.log("Before setup") }

    let mut system = kay::ActorSystem::new(kay::Networking::new(
        1,
        vec!["localhost:9999", "ws-client"],
        50_000,
        10,
        1,
    ));
    setup_all(&mut system);

    system.networking_connect();

    let browser_ui_id = citybound_common::browser_ui::BrowserUIID::spawn(&mut system.world());

    system.process_all_messages();

    js!{ console.log("After setup") }

    let mut main_loop = MainLoop {
        browser_ui_id,
        skip_turn: false,
    };

    unsafe { SYSTEM = Box::into_raw(Box::new(system)) };

    main_loop.frame();
}

#[derive(Copy, Clone)]
struct MainLoop {
    browser_ui_id: citybound_common::browser_ui::BrowserUIID,
    skip_turn: bool,
}

impl MainLoop {
    fn frame(&mut self) {
        let system = unsafe { &mut *SYSTEM };
        let world = &mut system.world();

        system.networking_send_and_receive();

        if !self.skip_turn {
            system.process_all_messages();

            self.browser_ui_id.on_frame(world);
            system.process_all_messages();

            system.networking_send_and_receive();
            system.process_all_messages();
        }

        js!{
            window.cbclient.setState(oldState => update(oldState, {
                system: {networkingTurns: {"$set":
                    @{system.networking_debug_all_n_turns()}
                }
            }}));

            window.cbclient.onFrame();
        }

        let mut next = self.clone();

        if self.skip_turn {
            next.skip_turn = false;
        } else {
            let maybe_sleep = system.networking_finish_turn();
            next.skip_turn = maybe_sleep.is_some();
        }

        ::stdweb::web::window().request_animation_frame(move |_| next.frame());
    }
}

mod planning_browser;
pub use planning_browser::*;
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#[macro_use]
extern crate criterion;
use criterion::Criterion;

use rand::seq::SliceRandom;
use rand::Rng;
use std::sync::{Arc, Mutex};
use tokio::runtime::Runtime;

extern crate arrow;
extern crate datafusion;

use arrow::{
    array::Float32Array,
    array::Float64Array,
    array::StringArray,
    datatypes::{DataType, Field, Schema},
    record_batch::RecordBatch,
};

use datafusion::datasource::MemTable;
use datafusion::error::Result;
use datafusion::execution::context::ExecutionContext;

fn query(ctx: Arc<Mutex<ExecutionContext>>, sql: &str) {
    let mut rt = Runtime::new().unwrap();

    // execute the query
    let df = ctx.lock().unwrap().sql(&sql).unwrap();
    rt.block_on(df.collect()).unwrap();
}

fn create_data(size: usize, null_density: f64) -> Vec<Option<f64>> {
    // use random numbers to avoid spurious compiler optimizations wrt to branching
    let mut rng = rand::thread_rng();

    (0..size)
        .map(|_| {
            if rng.gen::<f64>() > null_density {
                None
            } else {
                Some(rng.gen::<f64>())
            }
        })
        .collect()
}

fn create_context(
    partitions_len: usize,
    array_len: usize,
    batch_size: usize,
) -> Result<Arc<Mutex<ExecutionContext>>> {
    // define a schema.
    let schema = Arc::new(Schema::new(vec![
        Field::new("utf8", DataType::Utf8, false),
        Field::new("f32", DataType::Float32, false),
        Field::new("f64", DataType::Float64, false),
    ]));

    // define data.
    let partitions = (0..partitions_len)
        .map(|_| {
            (0..array_len / batch_size / partitions_len)
                .map(|i| {
                    // the 4 here is the number of different keys.
                    // a higher number increase sparseness
                    let vs = vec![0, 1, 2, 3];
                    let keys: Vec<String> = (0..batch_size)
                        .map(
                            // use random numbers to avoid spurious compiler optimizations wrt to branching
                            |_| format!("hi{:?}", vs.choose(&mut rand::thread_rng())),
                        )
                        .collect();
                    let keys: Vec<&str> = keys.iter().map(|e| &**e).collect();

                    let values = create_data(batch_size, 0.5);

                    RecordBatch::try_new(
                        schema.clone(),
                        vec![
                            Arc::new(StringArray::from(keys)),
                            Arc::new(Float32Array::from(vec![i as f32; batch_size])),
                            Arc::new(Float64Array::from(values)),
                        ],
                    )
                    .unwrap()
                })
                .collect::<Vec<_>>()
        })
        .collect::<Vec<_>>();

    let mut ctx = ExecutionContext::new();

    // declare a table in memory. In spark API, this corresponds to createDataFrame(...).
    let provider = MemTable::new(schema, partitions)?;
    ctx.register_table("t", Box::new(provider));

    Ok(Arc::new(Mutex::new(ctx)))
}

fn criterion_benchmark(c: &mut Criterion) {
    let partitions_len = 8;
    let array_len = 32768 * 2; // 2^16
    let batch_size = 2048; // 2^11
    let ctx = create_context(partitions_len, array_len, batch_size).unwrap();

    c.bench_function("aggregate_query_no_group_by 15 12", |b| {
        b.iter(|| {
            query(
                ctx.clone(),
                "SELECT MIN(f64), AVG(f64), COUNT(f64) \
                 FROM t",
            )
        })
    });

    c.bench_function("aggregate_query_group_by 15 12", |b| {
        b.iter(|| {
            query(
                ctx.clone(),
                "SELECT utf8, MIN(f64), AVG(f64), COUNT(f64) \
                 FROM t GROUP BY utf8",
            )
        })
    });

    c.bench_function("aggregate_query_group_by_with_filter 15 12", |b| {
        b.iter(|| {
            query(
                ctx.clone(),
                "SELECT utf8, MIN(f64), AVG(f64), COUNT(f64) \
                 FROM t \
                 WHERE f32 > 10 AND f32 < 20 GROUP BY utf8",
            )
        })
    });
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
<commit_msg>ARROW-10510: [Rust] [DataFusion] Benchmark COUNT(DISTINCT) queries.<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#[macro_use]
extern crate criterion;
use criterion::Criterion;

use rand::seq::SliceRandom;
use rand::Rng;
use std::sync::{Arc, Mutex};
use tokio::runtime::Runtime;

extern crate arrow;
extern crate datafusion;

use arrow::{
    array::Float32Array,
    array::Float64Array,
    array::StringArray,
    array::UInt64Array,
    datatypes::{DataType, Field, Schema},
    record_batch::RecordBatch,
};

use datafusion::datasource::MemTable;
use datafusion::error::Result;
use datafusion::execution::context::ExecutionContext;

fn query(ctx: Arc<Mutex<ExecutionContext>>, sql: &str) {
    let mut rt = Runtime::new().unwrap();

    // execute the query
    let df = ctx.lock().unwrap().sql(&sql).unwrap();
    rt.block_on(df.collect()).unwrap();
}

fn create_data(size: usize, null_density: f64) -> Vec<Option<f64>> {
    // use random numbers to avoid spurious compiler optimizations wrt to branching
    let mut rng = rand::thread_rng();

    (0..size)
        .map(|_| {
            if rng.gen::<f64>() > null_density {
                None
            } else {
                Some(rng.gen::<f64>())
            }
        })
        .collect()
}

fn create_integer_data(size: usize, value_density: f64) -> Vec<Option<u64>> {
    // use random numbers to avoid spurious compiler optimizations wrt to branching
    let mut rng = rand::thread_rng();

    (0..size)
        .map(|_| {
            if rng.gen::<f64>() > value_density {
                None
            } else {
                Some(rng.gen::<u64>())
            }
        })
        .collect()
}

fn create_context(
    partitions_len: usize,
    array_len: usize,
    batch_size: usize,
) -> Result<Arc<Mutex<ExecutionContext>>> {
    // define a schema.
    let schema = Arc::new(Schema::new(vec![
        Field::new("utf8", DataType::Utf8, false),
        Field::new("f32", DataType::Float32, false),
        Field::new("f64", DataType::Float64, false),
        // This field will contain integers randomly selected from a large
        // range of values, i.e. [0, u64::MAX], such that there are none (or
        // very few) repeated values.
        Field::new("u64_wide", DataType::UInt64, false),
        // This field will contain integers randomly selected from a narrow
        // range of values such that there are a few distinct values, but they
        // are repeated often.
        Field::new("u64_narrow", DataType::UInt64, false),
    ]));

    // define data.
    let partitions = (0..partitions_len)
        .map(|_| {
            (0..array_len / batch_size / partitions_len)
                .map(|i| {
                    // the 4 here is the number of different keys.
                    // a higher number increase sparseness
                    let vs = vec![0, 1, 2, 3];
                    let keys: Vec<String> = (0..batch_size)
                        .map(
                            // use random numbers to avoid spurious compiler optimizations wrt to branching
                            |_| format!("hi{:?}", vs.choose(&mut rand::thread_rng())),
                        )
                        .collect();
                    let keys: Vec<&str> = keys.iter().map(|e| &**e).collect();

                    let values = create_data(batch_size, 0.5);

                    // Integer values between [0, u64::MAX].
                    let integer_values_wide = create_integer_data(batch_size, 9.0);

                    // Integer values between [0, 9].
                    let integer_values_narrow_choices = (0..10).collect::<Vec<u64>>();
                    let integer_values_narrow = (0..batch_size)
                        .map(|_| {
                            *integer_values_narrow_choices
                                .choose(&mut rand::thread_rng())
                                .unwrap()
                        })
                        .collect::<Vec<u64>>();

                    RecordBatch::try_new(
                        schema.clone(),
                        vec![
                            Arc::new(StringArray::from(keys)),
                            Arc::new(Float32Array::from(vec![i as f32; batch_size])),
                            Arc::new(Float64Array::from(values)),
                            Arc::new(UInt64Array::from(integer_values_wide)),
                            Arc::new(UInt64Array::from(integer_values_narrow)),
                        ],
                    )
                    .unwrap()
                })
                .collect::<Vec<_>>()
        })
        .collect::<Vec<_>>();

    let mut ctx = ExecutionContext::new();

    // declare a table in memory. In spark API, this corresponds to createDataFrame(...).
    let provider = MemTable::new(schema, partitions)?;
    ctx.register_table("t", Box::new(provider));

    Ok(Arc::new(Mutex::new(ctx)))
}

fn criterion_benchmark(c: &mut Criterion) {
    let partitions_len = 8;
    let array_len = 32768 * 2; // 2^16
    let batch_size = 2048; // 2^11
    let ctx = create_context(partitions_len, array_len, batch_size).unwrap();

    c.bench_function("aggregate_query_no_group_by 15 12", |b| {
        b.iter(|| {
            query(
                ctx.clone(),
                "SELECT MIN(f64), AVG(f64), COUNT(f64) \
                 FROM t",
            )
        })
    });

    c.bench_function(
        "aggregate_query_no_group_by_count_distinct_wide 15 12",
        |b| {
            b.iter(|| {
                query(
                    ctx.clone(),
                    "SELECT COUNT(DISTINCT u64_wide) \
                 FROM t",
                )
            })
        },
    );

    c.bench_function(
        "aggregate_query_no_group_by_count_distinct_narrow 15 12",
        |b| {
            b.iter(|| {
                query(
                    ctx.clone(),
                    "SELECT COUNT(DISTINCT u64_narrow) \
                 FROM t",
                )
            })
        },
    );

    c.bench_function("aggregate_query_group_by 15 12", |b| {
        b.iter(|| {
            query(
                ctx.clone(),
                "SELECT utf8, MIN(f64), AVG(f64), COUNT(f64) \
                 FROM t GROUP BY utf8",
            )
        })
    });

    c.bench_function("aggregate_query_group_by_with_filter 15 12", |b| {
        b.iter(|| {
            query(
                ctx.clone(),
                "SELECT utf8, MIN(f64), AVG(f64), COUNT(f64) \
                 FROM t \
                 WHERE f32 > 10 AND f32 < 20 GROUP BY utf8",
            )
        })
    });
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
<|endoftext|>


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

use libc::{c_void, c_int, size_t};

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    // libc memchr
    #[cfg(any(not(target_os = "windows"),
              not(any(target_pointer_width = "32",
                      target_pointer_width = "64"))))]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc::memchr as libc_memchr;

        let p = unsafe {
            libc_memchr(
                haystack.as_ptr() as *const c_void,
                needle as c_int,
                haystack.len() as size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    // use fallback on windows, since it's faster
    #[cfg(all(target_os = "windows",
              any(target_pointer_width = "32",
                  target_pointer_width = "64")))]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memchr(needle, haystack)
    }

    memchr_specific(needle, haystack)
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {

    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc::memrchr as libc_memrchr;

        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
        if haystack.is_empty() {return None}
        let p = unsafe {
            libc_memrchr(
                haystack.as_ptr() as *const c_void,
                needle as c_int,
                haystack.len() as size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    #[cfg(all(not(target_os = "linux"),
              any(target_pointer_width = "32", target_pointer_width = "64")))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memrchr(needle, haystack)
    }

    // For the rare case of neither 32 bit nor 64-bit platform.
    #[cfg(all(not(target_os = "linux"),
              not(target_pointer_width = "32"),
              not(target_pointer_width = "64")))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        haystack.iter().rposition(|&b| b == needle)
    }

    memrchr_specific(needle, haystack)
}

#[allow(dead_code)]
mod fallback {
    use cmp;
    use usize;

    const LO_U64: u64 = 0x0101010101010101;
    const HI_U64: u64 = 0x8080808080808080;

    // use truncation
    const LO_USIZE: usize = LO_U64 as usize;
    const HI_USIZE: usize = HI_U64 as usize;

    /// Return `true` if `x` contains any zero byte.
    ///
    /// From *Matters Computational*, J. Arndt
    ///
    /// "The idea is to subtract one from each of the bytes and then look for
    /// bytes where the borrow propagated all the way to the most significant
    /// bit."
    #[inline]
    fn contains_zero_byte(x: usize) -> bool {
        x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
    }

    #[cfg(target_pointer_width = "32")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep
    }

    #[cfg(target_pointer_width = "64")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep = rep << 32 | rep;
        rep
    }

    /// Return the first index matching the byte `a` in `text`.
    pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned inital part, before the first word aligned address in text
        // - body, scan by 2 words at a time
        // - the last remaining part, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();

        // search up to an aligned boundary
        let align = (ptr as usize) & (usize::BYTES- 1);
        let mut offset;
        if align > 0 {
            offset = cmp::min(usize::BYTES - align, len);
            if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
                return Some(index);
            }
        } else {
            offset = 0;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        if len >= 2 * usize::BYTES {
            while offset <= len - 2 * usize::BYTES {
                unsafe {
                    let u = *(ptr.offset(offset as isize) as *const usize);
                    let v = *(ptr.offset((offset + usize::BYTES) as isize) as *const usize);

                    // break if there is a matching byte
                    let zu = contains_zero_byte(u ^ repeated_x);
                    let zv = contains_zero_byte(v ^ repeated_x);
                    if zu || zv {
                        break;
                    }
                }
                offset += usize::BYTES * 2;
            }
        }

        // find the byte after the point the body loop stopped
        text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
    }

    /// Return the last index matching the byte `a` in `text`.
    pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned tail, after the last word aligned address in text
        // - body, scan by 2 words at a time
        // - the first remaining bytes, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();

        // search to an aligned boundary
        let end_align = (ptr as usize + len) & (usize::BYTES - 1);
        let mut offset;
        if end_align > 0 {
            offset = len - cmp::min(usize::BYTES - end_align, len);
            if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                return Some(offset + index);
            }
        } else {
            offset = len;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        while offset >= 2 * usize::BYTES {
            unsafe {
                let u = *(ptr.offset(offset as isize - 2 * usize::BYTES as isize) as *const usize);
                let v = *(ptr.offset(offset as isize - usize::BYTES as isize) as *const usize);

                // break if there is a matching byte
                let zu = contains_zero_byte(u ^ repeated_x);
                let zv = contains_zero_byte(v ^ repeated_x);
                if zu || zv {
                    break;
                }
            }
            offset -= 2 * usize::BYTES;
        }

        // find the byte before the point the body loop stopped
        text[..offset].iter().rposition(|elt| *elt == x)
    }

    // test fallback implementations on all plattforms
    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}

#[cfg(test)]
mod tests {
    // test the implementations for the current plattform
    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}
<commit_msg>Use memrchr bindings provided by libc<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    // libc memchr
    #[cfg(not(target_os = "windows"))]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        let p = unsafe {
            libc::memchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    // use fallback on windows, since it's faster
    #[cfg(target_os = "windows")]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memchr(needle, haystack)
    }

    memchr_specific(needle, haystack)
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {

    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
        if haystack.is_empty() {return None}
        let p = unsafe {
            libc::memrchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    #[cfg(not(target_os = "linux"))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        haystack.iter().rposition(|&b| b == needle)
    }

    memrchr_specific(needle, haystack)
}

#[allow(dead_code)]
mod fallback {
    use cmp;
    use usize;

    const LO_U64: u64 = 0x0101010101010101;
    const HI_U64: u64 = 0x8080808080808080;

    // use truncation
    const LO_USIZE: usize = LO_U64 as usize;
    const HI_USIZE: usize = HI_U64 as usize;

    /// Return `true` if `x` contains any zero byte.
    ///
    /// From *Matters Computational*, J. Arndt
    ///
    /// "The idea is to subtract one from each of the bytes and then look for
    /// bytes where the borrow propagated all the way to the most significant
    /// bit."
    #[inline]
    fn contains_zero_byte(x: usize) -> bool {
        x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
    }

    #[cfg(target_pointer_width = "32")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep
    }

    #[cfg(target_pointer_width = "64")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep = rep << 32 | rep;
        rep
    }

    /// Return the first index matching the byte `a` in `text`.
    pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned inital part, before the first word aligned address in text
        // - body, scan by 2 words at a time
        // - the last remaining part, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();

        // search up to an aligned boundary
        let align = (ptr as usize) & (usize::BYTES- 1);
        let mut offset;
        if align > 0 {
            offset = cmp::min(usize::BYTES - align, len);
            if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
                return Some(index);
            }
        } else {
            offset = 0;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        if len >= 2 * usize::BYTES {
            while offset <= len - 2 * usize::BYTES {
                unsafe {
                    let u = *(ptr.offset(offset as isize) as *const usize);
                    let v = *(ptr.offset((offset + usize::BYTES) as isize) as *const usize);

                    // break if there is a matching byte
                    let zu = contains_zero_byte(u ^ repeated_x);
                    let zv = contains_zero_byte(v ^ repeated_x);
                    if zu || zv {
                        break;
                    }
                }
                offset += usize::BYTES * 2;
            }
        }

        // find the byte after the point the body loop stopped
        text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
    }

    /// Return the last index matching the byte `a` in `text`.
    pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned tail, after the last word aligned address in text
        // - body, scan by 2 words at a time
        // - the first remaining bytes, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();

        // search to an aligned boundary
        let end_align = (ptr as usize + len) & (usize::BYTES - 1);
        let mut offset;
        if end_align > 0 {
            offset = len - cmp::min(usize::BYTES - end_align, len);
            if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                return Some(offset + index);
            }
        } else {
            offset = len;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        while offset >= 2 * usize::BYTES {
            unsafe {
                let u = *(ptr.offset(offset as isize - 2 * usize::BYTES as isize) as *const usize);
                let v = *(ptr.offset(offset as isize - usize::BYTES as isize) as *const usize);

                // break if there is a matching byte
                let zu = contains_zero_byte(u ^ repeated_x);
                let zv = contains_zero_byte(v ^ repeated_x);
                if zu || zv {
                    break;
                }
            }
            offset -= 2 * usize::BYTES;
        }

        // find the byte before the point the body loop stopped
        text[..offset].iter().rposition(|elt| *elt == x)
    }

    // test fallback implementations on all plattforms
    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}

#[cfg(test)]
mod tests {
    // test the implementations for the current plattform
    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}
<|endoftext|>


<commit_before>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```ignore
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Directory used to store incremental data for the compiler (when
//!     # incremental is enabled.
//!     incremental/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use crate::core::Workspace;
use crate::util::{CargoResult, Config, FileLock, Filesystem};

/// Contains the paths of all target output locations.
///
/// See module docs for more information.
pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    incremental: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
    /// The lock file for a build, will be unlocked when this struct is `drop`ped.
    _lock: FileLock,
}

pub fn is_bad_artifact_name(name: &str) -> bool {
    ["deps", "examples", "build", "native", "incremental"]
        .iter()
        .any(|&reserved| reserved == name)
}

impl Layout {
    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    ///
    /// Differs from `at` in that this calculates the root path from the workspace target directory,
    /// adding the target triple and the profile (debug, release, ...).
    pub fn new(ws: &Workspace<'_>, triple: Option<&str>, dest: &str) -> CargoResult<Layout> {
        let mut path = ws.target_dir();
        // Flexible target specifications often point at json files, so interpret
        // the target triple as a Path and then just use the file stem as the
        // component for the directory name in that case.
        if let Some(triple) = triple {
            let triple = Path::new(triple);
            if triple.extension().and_then(|s| s.to_str()) == Some("json") {
                path.push(
                    triple
                        .file_stem()
                        .ok_or_else(|| failure::format_err!("invalid target"))?,
                );
            } else {
                path.push(triple);
            }
        }
        path.push(dest);
        Layout::at(ws.config(), path)
    }

    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    pub fn at(config: &Config, root: Filesystem) -> CargoResult<Layout> {
        // For now we don't do any more finer-grained locking on the artifact
        // directory, so just lock the entire thing for the duration of this
        // compile.
        let lock = root.open_rw(".cargo-lock", config, "build directory")?;
        let root = root.into_path_unlocked();

        Ok(Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            incremental: root.join("incremental"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root,
            _lock: lock,
        })
    }

    #[cfg(not(target_os = "macos"))]
    fn exclude_from_backups(&self, _: &Path) {}

    #[cfg(target_os = "macos")]
    /// Marks files or directories as excluded from Time Machine on macOS
    ///
    /// This is recommended to prevent derived/temporary files from bloating backups.
    fn exclude_from_backups(&self, path: &Path) {
        use core_foundation::base::TCFType;
        use core_foundation::{number, string, url};
        use std::ptr;

        // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey
        let is_excluded_key: Result<string::CFString, _> = "NSURLIsExcludedFromBackupKey".parse();
        let path = url::CFURL::from_path(path, false);
        if let (Some(path), Ok(is_excluded_key)) = (path, is_excluded_key) {
            unsafe {
                url::CFURLSetResourcePropertyForKey(
                    path.as_concrete_TypeRef(),
                    is_excluded_key.as_concrete_TypeRef(),
                    number::kCFBooleanTrue as *const _,
                    ptr::null_mut(),
                );
            }
        }
        // Errors are ignored, since it's an optional feature and failure
        // doesn't prevent Cargo from working
    }

    /// Makes sure all directories stored in the Layout exist on the filesystem.
    pub fn prepare(&mut self) -> io::Result<()> {
        if fs::metadata(&self.root).is_err() {
            fs::create_dir_all(&self.root)?;
        }

        self.exclude_from_backups(&self.root);

        mkdir(&self.deps)?;
        mkdir(&self.native)?;
        mkdir(&self.incremental)?;
        mkdir(&self.fingerprint)?;
        mkdir(&self.examples)?;
        mkdir(&self.build)?;

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                fs::create_dir(dir)?;
            }
            Ok(())
        }
    }

    /// Fetch the root path.
    pub fn dest(&self) -> &Path {
        &self.root
    }
    /// Fetch the deps path.
    pub fn deps(&self) -> &Path {
        &self.deps
    }
    /// Fetch the examples path.
    pub fn examples(&self) -> &Path {
        &self.examples
    }
    /// Fetch the root path.
    pub fn root(&self) -> &Path {
        &self.root
    }
    /// Fetch the incremental path.
    pub fn incremental(&self) -> &Path {
        &self.incremental
    }
    /// Fetch the fingerprint path.
    pub fn fingerprint(&self) -> &Path {
        &self.fingerprint
    }
    /// Fetch the build path.
    pub fn build(&self) -> &Path {
        &self.build
    }
}
<commit_msg>Only execute `exclude_from_backups` once<commit_after>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```ignore
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Directory used to store incremental data for the compiler (when
//!     # incremental is enabled.
//!     incremental/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use crate::core::Workspace;
use crate::util::{CargoResult, Config, FileLock, Filesystem};

/// Contains the paths of all target output locations.
///
/// See module docs for more information.
pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    incremental: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
    /// The lock file for a build, will be unlocked when this struct is `drop`ped.
    _lock: FileLock,
}

pub fn is_bad_artifact_name(name: &str) -> bool {
    ["deps", "examples", "build", "native", "incremental"]
        .iter()
        .any(|&reserved| reserved == name)
}

impl Layout {
    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    ///
    /// Differs from `at` in that this calculates the root path from the workspace target directory,
    /// adding the target triple and the profile (debug, release, ...).
    pub fn new(ws: &Workspace<'_>, triple: Option<&str>, dest: &str) -> CargoResult<Layout> {
        let mut path = ws.target_dir();
        // Flexible target specifications often point at json files, so interpret
        // the target triple as a Path and then just use the file stem as the
        // component for the directory name in that case.
        if let Some(triple) = triple {
            let triple = Path::new(triple);
            if triple.extension().and_then(|s| s.to_str()) == Some("json") {
                path.push(
                    triple
                        .file_stem()
                        .ok_or_else(|| failure::format_err!("invalid target"))?,
                );
            } else {
                path.push(triple);
            }
        }
        path.push(dest);
        Layout::at(ws.config(), path)
    }

    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    pub fn at(config: &Config, root: Filesystem) -> CargoResult<Layout> {
        // For now we don't do any more finer-grained locking on the artifact
        // directory, so just lock the entire thing for the duration of this
        // compile.
        let lock = root.open_rw(".cargo-lock", config, "build directory")?;
        let root = root.into_path_unlocked();

        Ok(Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            incremental: root.join("incremental"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root,
            _lock: lock,
        })
    }

    #[cfg(not(target_os = "macos"))]
    fn exclude_from_backups(&self, _: &Path) {}

    #[cfg(target_os = "macos")]
    /// Marks files or directories as excluded from Time Machine on macOS
    ///
    /// This is recommended to prevent derived/temporary files from bloating backups.
    fn exclude_from_backups(&self, path: &Path) {
        use core_foundation::base::TCFType;
        use core_foundation::{number, string, url};
        use std::ptr;

        // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey
        let is_excluded_key: Result<string::CFString, _> = "NSURLIsExcludedFromBackupKey".parse();
        let path = url::CFURL::from_path(path, false);
        if let (Some(path), Ok(is_excluded_key)) = (path, is_excluded_key) {
            unsafe {
                url::CFURLSetResourcePropertyForKey(
                    path.as_concrete_TypeRef(),
                    is_excluded_key.as_concrete_TypeRef(),
                    number::kCFBooleanTrue as *const _,
                    ptr::null_mut(),
                );
            }
        }
        // Errors are ignored, since it's an optional feature and failure
        // doesn't prevent Cargo from working
    }

    /// Makes sure all directories stored in the Layout exist on the filesystem.
    pub fn prepare(&mut self) -> io::Result<()> {
        if fs::metadata(&self.root).is_err() {
            fs::create_dir_all(&self.root)?;
            self.exclude_from_backups(&self.root);
        }

        mkdir(&self.deps)?;
        mkdir(&self.native)?;
        mkdir(&self.incremental)?;
        mkdir(&self.fingerprint)?;
        mkdir(&self.examples)?;
        mkdir(&self.build)?;

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                fs::create_dir(dir)?;
            }
            Ok(())
        }
    }

    /// Fetch the root path.
    pub fn dest(&self) -> &Path {
        &self.root
    }
    /// Fetch the deps path.
    pub fn deps(&self) -> &Path {
        &self.deps
    }
    /// Fetch the examples path.
    pub fn examples(&self) -> &Path {
        &self.examples
    }
    /// Fetch the root path.
    pub fn root(&self) -> &Path {
        &self.root
    }
    /// Fetch the incremental path.
    pub fn incremental(&self) -> &Path {
        &self.incremental
    }
    /// Fetch the fingerprint path.
    pub fn fingerprint(&self) -> &Path {
        &self.fingerprint
    }
    /// Fetch the build path.
    pub fn build(&self) -> &Path {
        &self.build
    }
}
<|endoftext|>


<commit_before>

fn main() {

    let link_type = "dylib";
    let lib_name = "gdal";

    #[cfg(windows)]
    {
        use std::path::Path;
        use std::env;

        // get the path to GDAL_HOME
        let home_path = env::var("GDAL_HOME").expect("Environment variable $GDAL_HOME not found!");

        // detect the path to gdal_i.lib (works for MSVC and GNU)
        let lib_suffix = "_i";
        let lib_search_path = Path::new(&home_path).join("lib");
        let lib_path = lib_search_path.join(&format!("{}{}.lib", lib_name, lib_suffix));

        if lib_search_path.exists() && lib_path.exists() {
            println!("cargo:rustc-link-search={}", lib_search_path.to_string_lossy());
            println!("cargo:rustc-link-lib={}={}", link_type, format!("{}{}",lib_name, lib_suffix));
        } else {

            #[cfg(target_env="msvc")]
            {
                panic!("windows-msvc requires gdal_i.lib to be found in $GDAL_HOME\\lib.");
            }

            #[cfg(target_env="gnu")]
            {
                // detect if a gdal{version}.dll is available
                let versions = [201, 200, 111, 110];
                let bin_path = Path::new(&home_path).join("bin");
                if let Some(version) = versions.iter().find(|v| bin_path.join(&format!("{}{}.dll", lib_name, v)).exists()){
                    println!("cargo:rustc-link-search={}", bin_path.to_string_lossy());
                    println!("cargo:rustc-link-lib={}={}", link_type, format!("{}{}",lib_name, version));
                }
                else {
                    panic!("windows-gnu requires either gdal_i.lib in $GDAL_HOME\\lib OR gdal{version}.dll in $GDAL_HOME\\bin.");
                }
            }
        }
    }

    #[cfg(unix)]
    {
        println!("cargo:rustc-link-lib={}={}", link_type, lib_name);
    }
}<commit_msg>Remove extra whitespace<commit_after>

fn main() {

    let link_type = "dylib";
    let lib_name = "gdal";

    #[cfg(windows)]
    {
        use std::path::Path;
        use std::env;

        // get the path to GDAL_HOME
        let home_path = env::var("GDAL_HOME").expect("Environment variable $GDAL_HOME not found!");

        // detect the path to gdal_i.lib (works for MSVC and GNU)
        let lib_suffix = "_i";
        let lib_search_path = Path::new(&home_path).join("lib");
        let lib_path = lib_search_path.join(&format!("{}{}.lib", lib_name, lib_suffix));

        if lib_search_path.exists() && lib_path.exists() {
            println!("cargo:rustc-link-search={}", lib_search_path.to_string_lossy());
            println!("cargo:rustc-link-lib={}={}", link_type, format!("{}{}",lib_name, lib_suffix));
        } else {

            #[cfg(target_env="msvc")]
            {
                panic!("windows-msvc requires gdal_i.lib to be found in $GDAL_HOME\\lib.");
            }

            #[cfg(target_env="gnu")]
            {
                // detect if a gdal{version}.dll is available
                let versions = [201, 200, 111, 110];
                let bin_path = Path::new(&home_path).join("bin");
                if let Some(version) = versions.iter().find(|v| bin_path.join(&format!("{}{}.dll", lib_name, v)).exists()){
                    println!("cargo:rustc-link-search={}", bin_path.to_string_lossy());
                    println!("cargo:rustc-link-lib={}={}", link_type, format!("{}{}",lib_name, version));
                }
                else {
                    panic!("windows-gnu requires either gdal_i.lib in $GDAL_HOME\\lib OR gdal{version}.dll in $GDAL_HOME\\bin.");
                }
            }
        }
    }

    #[cfg(unix)]
    {
        println!("cargo:rustc-link-lib={}={}", link_type, lib_name);
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::any::Any;
use std::marker::PhantomData;
use serde::{Serialize, Serializer, Error, de};

use {ExtendedTime, StewardRc, FieldRc, ColumnId, Column, Basics, EventFn, PredictorFn,};

enum Void {}

macro_rules! type_list_definitions {
($Trait: ident [$($bounded:tt)*] [$($unbounded: ident),*], $Wrapper: ident, $List: ident, $User: ident) => {
pub struct $Wrapper <$($bounded)* T: $Trait<$($unbounded),*>>($(PhantomData <$unbounded>,)* PhantomData <T>, Void);
pub trait $User<$($bounded)*> {
  fn apply<C: $Trait <$($unbounded),*>>(&mut self);
}
pub trait $List<$($bounded)*>: Any {
  fn apply<U: $User>(user: &mut U);
}
impl<$($bounded)* T: $Trait <$($unbounded),*>> $List <$($unbounded),*> for $Wrapper<$($unbounded,)* T> {
  #[inline]
  fn apply<U: $User>(user: &mut U) {
    user.apply::<T>();
  }
}
tuple_impls! ([$($bounded)*] [$($unbounded),*], $List, $User, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31);
};
}
macro_rules! tuple_impls {
  ([$($bounded:tt)*] [$unbounded: ident], $List: ident, $User: ident, $TL: ident $(, $T: ident)*) => {
    impl<$($bounded)* $($T,)* $TL> $List<$unbounded> for ($($T,)* $TL,)
      where $($T: $List<$unbounded>,)* $TL: $List<$unbounded>
    {
      #[inline]
      fn apply <U: $User<$unbounded>> (user: &mut U) {
        $($T::apply(user);)*
        $TL::apply(user);
      }
    }
    tuple_impls! ([$($bounded)*] [$unbounded], $List, $User, $($T),*);
  };
  ([$($bounded:tt)*] [], $List: ident, $User: ident, $TL: ident $(, $T: ident)*) => {
    impl<$($bounded)* $($T,)* $TL> $List<> for ($($T,)* $TL,)
      where $($T: $List<>,)* $TL: $List<>
    {
      #[inline]
      fn apply <U: $User> (user: &mut U) {
        $($T::apply(user);)*
        $TL::apply(user);
      }
    }
    tuple_impls! ([$($bounded)*] [], $List, $User, $($T),*);
  };
  ([$($bounded:tt)*] [$($unbounded: ident),*], $List: ident, $User: ident,) => {};
}
macro_rules! pair_null_impls {
([$($bounded0:tt)*] [$($unbounded0: ident),*], $Wrapper0: ident, $List0: ident, $User0: ident, [$($bounded1:tt)*] [$($unbounded1: ident),*], $Wrapper1: ident, $List1: ident, $User1: ident) => {
impl<$($bounded1)* T> $List1 for $Wrapper0<$($bounded)* T> {
  #[inline]
  fn apply<U: $User1>(_: &mut U) {}
}
impl<$($bounded0)* T> $List0 for $Wrapper1<$($bounded)* T> {
  #[inline]
  fn apply<U: $User0>(_: &mut U) {}
}
};
}
macro_rules! all_null_impls {
([$Wrapper0: ident, $List0: ident, $User0: ident] $(, [$Wrapper: ident, $List: ident, $User: ident])*) => {
  $(pair_null_impls! ($Wrapper0, $List0, $User0, $Wrapper, $List, $User);)*
  all_null_impls! ($([$Wrapper, $List, $User]),*);
};
() => {};
}
macro_rules! all_list_definitions {
($([$Trait: ident [$($bounded:tt)*] [$($unbounded: ident),*],  $Wrapper: ident, $List: ident, $User: ident],)*) => {
  $(type_list_definitions! ($Trait[$($bounded)*] [$($unbounded),*], $Wrapper, $List, $User);)*
  all_null_impls! ($([$Wrapper, $List, $User]),*);
};
}

// Today I Learned that macro hygiene is not applied to type parameter lists
//
// macro_rules! escalate {
// ([$first:tt $($whatever:tt)*] $($T: ident)*) => {escalate! ([$($whatever)*] foo $($T)*);};
// ([] $($T: ident)*) => {tuple_impls! ($($T),*);};
// }
// escalate! ([!!!!!!!! !!!!!!!! !!!!!!!! !!!!!!!!]);
//

all_list_definitions! (
  [Column[][], ColumnType, ColumnList, ColumnListUser],
  [EventFn[B: Basics,][B], EventType, EventList, EventListUser],
);

fn check_equality<C: Column>(first: &FieldRc, second: &FieldRc)->bool {
  ::unwrap_field::<C>(first) == ::unwrap_field::<C>(second)
}
pub struct FieldEqualityTable (HashMap<ColumnId, fn(&FieldRc, &FieldRc)->bool>);
impl ColumnListUser for FieldEqualityTable{
  fn apply<C: Column>(&mut self) {
    self.0.insert(C::column_id(), check_equality::<C>);
  }
}
impl FieldEqualityTable{
  pub fn new <C: ColumnList>()->FieldEqualityTable{
    let mut result = FieldEqualityTable(HashMap::new());
    C::apply (&mut result);
    result
  }
  pub fn fields_are_equal(&self, column_id: ColumnId, first: & FieldRc, second: & FieldRc)->bool {
    (self.0.get (&column_id).expect ("Column missing from equality table; did you forget to list a column in Basics::Columns?")) (first, second)
  }
  pub fn options_are_equal(&self, column_id: ColumnId, first: Option <& FieldRc>, second: Option <& FieldRc>)->bool {
    match (first, second) {
      (None, None) => true,
      (Some (first), Some (second)) => self.fields_are_equal (column_id, first, second),
      _ => false,
    }
  }
}

  fn serialize_column<C: Column, S: Serializer>(field: &FieldRc,
                                                serializer: &mut S)
                                                -> Result<(), S::Error> {
    try!(::unwrap_field::<C>(field).serialize(serializer));
    Ok(())
  }

  fn deserialize_column<B: Basics, C: Column, M: de::MapVisitor>
    (visitor: &mut M)
     -> Result<(FieldRc, ExtendedTime<B>), M::Error> {
    let (data, time) = try!(visitor.visit_value::<(C::FieldType, ExtendedTime<B>)>());
    Ok((StewardRc::new(data), time))
  }

  pub struct FieldSerializationTable<S: Serializer>(HashMap<ColumnId,
                                                           fn(&FieldRc, &mut S)
                                                              -> Result<(), S::Error>>);
  pub struct FieldDeserializationTable <B: Basics, M: de::MapVisitor> (HashMap<ColumnId, fn (&mut M)->Result <(FieldRc, ExtendedTime <B>), M::Error>>);

  impl<S: Serializer> ColumnListUser for FieldSerializationTable<S> {
    fn apply<C: Column>(&mut self) {
      self.0.insert(C::column_id(), serialize_column::<C, S>);
    }
  }
  impl<B: Basics, M: de::MapVisitor> ColumnListUser for FieldDeserializationTable <B, M> {
    fn apply<C: Column>(&mut self) {
      self.0.insert(C::column_id(), deserialize_column::<B, C, M>);
    }
  }
  impl<S: Serializer> FieldSerializationTable<S> {
  pub fn new <C: ColumnList>()->FieldSerializationTable <S> {
    let mut result = FieldSerializationTable(HashMap::new());
    C::apply (&mut result);
    result
  }
  pub fn serialize_field(&self, column_id: ColumnId, first: & FieldRc,
                                                  serializer: &mut S)->Result<(), S::Error>{
    use serde::ser::Error;
    try!(self.0.get (&column_id).ok_or (S::Error::custom ("Column missing from serialization table; did you forget to list a column in Basics::Columns?"))) (first, serializer)
  }
  }
  impl<B: Basics, M: de::MapVisitor> FieldDeserializationTable <B, M> {
  pub fn new <C: ColumnList>()->FieldDeserializationTable <B, M> {
    let mut result = FieldDeserializationTable (HashMap::new());
    C::apply (&mut result);
    result
  }
  pub fn deserialize_field(&self, column_id: ColumnId, visitor: &mut M)->Result<(FieldRc, ExtendedTime<B>), M::Error>{
    try!(self.0.get (&column_id).ok_or (M::Error::custom ("Column missing from deserialization table; did you forget to list a column in Basics::Columns?"))) (visitor)
  }
  }

<commit_msg>Reverted to an earlier version that didn't consider generics (fixed build)<commit_after>use std::collections::HashMap;
use std::any::Any;
use std::marker::PhantomData;
use serde::{Serialize, Serializer, Error, de};

use {ExtendedTime, StewardRc, FieldRc, ColumnId, Column, Basics, EventFn, PredictorFn,};

enum Void {}

macro_rules! type_list_definitions {
($Trait: ident, $Wrapper: ident, $List: ident, $User: ident) => {
pub struct $Wrapper<T: $Trait>(PhantomData <T>, Void);
pub trait $User {
  fn apply<C: $Trait>(&mut self);
}
pub trait $List: Any {
  fn apply<U: $User>(user: &mut U);
}
impl<T: $Trait> $List for $Wrapper<T> {
  #[inline]
  fn apply<U: $User>(user: &mut U) {
    user.apply::<T>();
  }
}
tuple_impls! ($List, $User, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31);
};
}
macro_rules! tuple_impls {
  ($List: ident, $User: ident, $TL: ident $(, $T: ident)*) => {
    impl<$($T,)* $TL> $List for ($($T,)* $TL,)
      where $($T: $List,)* $TL: ColumnList
    {
      #[inline]
      fn apply <U: $User> (user: &mut U) {
        $($T::apply(user);)*
        $TL::apply(user);
      }
    }
    tuple_impls! ($List, $User, $($T),*);
  };
  ($List: ident, $User: ident,) => {};
}
macro_rules! pair_null_impls {
($Trait0: ident, $Wrapper0: ident, $List0: ident, $User0: ident, $Trait1: ident, $Wrapper1: ident, $List1: ident, $User1: ident) => {
impl<T> $List1 for $Wrapper0<T> {
  #[inline]
  fn apply<U: $User1>(_: &mut U) {}
}
impl<T> $List0 for $Wrapper1<T> {
  #[inline]
  fn apply<U: $User0>(_: &mut U) {}
}
};
}
macro_rules! all_null_impls {
([$Trait0: ident, $Wrapper0: ident, $List0: ident, $User0: ident] $(, [$Trait: ident, $Wrapper: ident, $List: ident, $User: ident])*) => {
  $(pair_null_impls! ($Trait0, $Wrapper0, $List0, $User0, $Trait, $Wrapper, $List, $User);)*
  all_null_impls! ($([$Trait, $Wrapper, $List, $User]),*);
};
() => {};
}
macro_rules! all_list_definitions {
($([$Trait: ident, $Wrapper: ident, $List: ident, $User: ident],)*) => {
  $(type_list_definitions! ($Trait, $Wrapper, $List, $User);)*
  all_null_impls! ($([$Trait, $Wrapper, $List, $User]),*);
};
}

// Today I Learned that macro hygiene is not applied to type parameter lists
//
// macro_rules! escalate {
// ([$first:tt $($whatever:tt)*] $($T: ident)*) => {escalate! ([$($whatever)*] foo $($T)*);};
// ([] $($T: ident)*) => {tuple_impls! ($($T),*);};
// }
// escalate! ([!!!!!!!! !!!!!!!! !!!!!!!! !!!!!!!!]);
//

all_list_definitions! (
  [Column, ColumnType, ColumnList, ColumnListUser],
  //[EventFn, EventType, EventList, EventListUser],
);

fn check_equality<C: Column>(first: &FieldRc, second: &FieldRc)->bool {
  ::unwrap_field::<C>(first) == ::unwrap_field::<C>(second)
}
pub struct FieldEqualityTable (HashMap<ColumnId, fn(&FieldRc, &FieldRc)->bool>);
impl ColumnListUser for FieldEqualityTable{
  fn apply<C: Column>(&mut self) {
    self.0.insert(C::column_id(), check_equality::<C>);
  }
}
impl FieldEqualityTable{
  pub fn new <C: ColumnList>()->FieldEqualityTable{
    let mut result = FieldEqualityTable(HashMap::new());
    C::apply (&mut result);
    result
  }
  pub fn fields_are_equal(&self, column_id: ColumnId, first: & FieldRc, second: & FieldRc)->bool {
    (self.0.get (&column_id).expect ("Column missing from equality table; did you forget to list a column in Basics::Columns?")) (first, second)
  }
  pub fn options_are_equal(&self, column_id: ColumnId, first: Option <& FieldRc>, second: Option <& FieldRc>)->bool {
    match (first, second) {
      (None, None) => true,
      (Some (first), Some (second)) => self.fields_are_equal (column_id, first, second),
      _ => false,
    }
  }
}

  fn serialize_column<C: Column, S: Serializer>(field: &FieldRc,
                                                serializer: &mut S)
                                                -> Result<(), S::Error> {
    try!(::unwrap_field::<C>(field).serialize(serializer));
    Ok(())
  }

  fn deserialize_column<B: Basics, C: Column, M: de::MapVisitor>
    (visitor: &mut M)
     -> Result<(FieldRc, ExtendedTime<B>), M::Error> {
    let (data, time) = try!(visitor.visit_value::<(C::FieldType, ExtendedTime<B>)>());
    Ok((StewardRc::new(data), time))
  }

  pub struct FieldSerializationTable<S: Serializer>(HashMap<ColumnId,
                                                           fn(&FieldRc, &mut S)
                                                              -> Result<(), S::Error>>);
  pub struct FieldDeserializationTable <B: Basics, M: de::MapVisitor> (HashMap<ColumnId, fn (&mut M)->Result <(FieldRc, ExtendedTime <B>), M::Error>>);

  impl<S: Serializer> ColumnListUser for FieldSerializationTable<S> {
    fn apply<C: Column>(&mut self) {
      self.0.insert(C::column_id(), serialize_column::<C, S>);
    }
  }
  impl<B: Basics, M: de::MapVisitor> ColumnListUser for FieldDeserializationTable <B, M> {
    fn apply<C: Column>(&mut self) {
      self.0.insert(C::column_id(), deserialize_column::<B, C, M>);
    }
  }
  impl<S: Serializer> FieldSerializationTable<S> {
  pub fn new <C: ColumnList>()->FieldSerializationTable <S> {
    let mut result = FieldSerializationTable(HashMap::new());
    C::apply (&mut result);
    result
  }
  pub fn serialize_field(&self, column_id: ColumnId, first: & FieldRc,
                                                  serializer: &mut S)->Result<(), S::Error>{
    use serde::ser::Error;
    try!(self.0.get (&column_id).ok_or (S::Error::custom ("Column missing from serialization table; did you forget to list a column in Basics::Columns?"))) (first, serializer)
  }
  }
  impl<B: Basics, M: de::MapVisitor> FieldDeserializationTable <B, M> {
  pub fn new <C: ColumnList>()->FieldDeserializationTable <B, M> {
    let mut result = FieldDeserializationTable (HashMap::new());
    C::apply (&mut result);
    result
  }
  pub fn deserialize_field(&self, column_id: ColumnId, visitor: &mut M)->Result<(FieldRc, ExtendedTime<B>), M::Error>{
    try!(self.0.get (&column_id).ok_or (M::Error::custom ("Column missing from deserialization table; did you forget to list a column in Basics::Columns?"))) (visitor)
  }
  }

<|endoftext|>


<commit_before>use super::*;

#[test]
fn from_vec() {
	let q = Queue::from(vec![1, 2, 3]);
	assert_eq!(&vec![1, 2, 3], q.vec());
}

#[test]
fn from_empty_vec() {
	let v: Vec<i64> = Vec::new();
	let q = Queue::from(v.clone());
	assert_eq!(&v, q.vec());
}

#[test]
fn queue() {
	let mut q = Queue::new();
	assert_eq!(q.queue("hello"), Ok(1));
}

#[test]
fn dequeue() {
	let mut q = Queue::new();
	q.queue("hello").unwrap();
	assert_eq!(q.dequeue(), Some("hello"));
}

#[test]
fn no_capacity() {
	let q: Queue<u8> = Queue::new();
	assert_eq!(q.capacity(), None);
}

#[test]
fn some_capacity() {
	let q: Queue<u8> = Queue::with_capacity(12);
	assert_eq!(q.capacity(), Some(12));
}

#[test]
fn queue_full_capacity() {
	let mut q: Queue<u8> = Queue::with_capacity(0);
	assert_eq!(q.queue(3), Err(()));
}

#[test]
fn vec_empty() {
	let q: Queue<i64> = Queue::new();
	let v: Vec<i64> = Vec::new();
	assert_eq!(&v, q.vec());
}

#[test]
fn vec_some() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	q.queue(2).unwrap();
	q.queue(3).unwrap();
	let v = vec![1, 2, 3];
	assert_eq!(&v, q.vec());
}

#[test]
fn peek_at_empty() {
	let q: Queue<u8> = Queue::with_capacity(1);
	assert_eq!(q.peek(), None);
}

#[test]
fn peek_at_something() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	assert_eq!(q.peek(), Some(1));
}

#[test]
fn force_queue_with_capacity() {
	let mut q: Queue<u8> = Queue::with_capacity(1);
	q.queue(1).unwrap();
	let _ = q.force_queue(2);
	assert_eq!(q.peek(), Some(2));
}

#[test]
fn force_queue_with_capacity_check_size() {
	let mut q = Queue::with_capacity(1);
	q.queue(1).unwrap();
	assert_eq!(1, q.force_queue(2));
}

#[test]
fn force_queue_no_capacity() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	assert_eq!(2, q.force_queue(2));
}

#[test]
fn no_len() {
	let q: Queue<u8> = Queue::new();
	assert_eq!(q.len(), 0);
}

#[test]
fn some_len() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	q.queue(2).unwrap();
	assert_eq!(q.len(), 2);
}

#[test]
fn is_empty_empty() {
	let q: Queue<i64> = Queue::new();
	assert_eq!(q.is_empty(), true);
}

#[test]
fn is_empty_some() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	assert_eq!(q.is_empty(), false);
}
<commit_msg>another dequeue() test for 100% code coverage<commit_after>use super::*;

#[test]
fn from_vec() {
	let q = Queue::from(vec![1, 2, 3]);
	assert_eq!(&vec![1, 2, 3], q.vec());
}

#[test]
fn from_empty_vec() {
	let v: Vec<i64> = Vec::new();
	let q = Queue::from(v.clone());
	assert_eq!(&v, q.vec());
}

#[test]
fn queue() {
	let mut q = Queue::new();
	assert_eq!(q.queue("hello"), Ok(1));
}

#[test]
fn dequeue() {
	let mut q = Queue::new();
	q.queue("hello").unwrap();
	assert_eq!(q.dequeue(), Some("hello"));
}

#[test]
fn dequeue_empty() {
	let mut q: Queue<i64> = Queue::new();
	assert_eq!(q.dequeue(), None);
}

#[test]
fn no_capacity() {
	let q: Queue<u8> = Queue::new();
	assert_eq!(q.capacity(), None);
}

#[test]
fn some_capacity() {
	let q: Queue<u8> = Queue::with_capacity(12);
	assert_eq!(q.capacity(), Some(12));
}

#[test]
fn queue_full_capacity() {
	let mut q: Queue<u8> = Queue::with_capacity(0);
	assert_eq!(q.queue(3), Err(()));
}

#[test]
fn vec_empty() {
	let q: Queue<i64> = Queue::new();
	let v: Vec<i64> = Vec::new();
	assert_eq!(&v, q.vec());
}

#[test]
fn vec_some() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	q.queue(2).unwrap();
	q.queue(3).unwrap();
	let v = vec![1, 2, 3];
	assert_eq!(&v, q.vec());
}

#[test]
fn peek_at_empty() {
	let q: Queue<u8> = Queue::with_capacity(1);
	assert_eq!(q.peek(), None);
}

#[test]
fn peek_at_something() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	assert_eq!(q.peek(), Some(1));
}

#[test]
fn force_queue_with_capacity() {
	let mut q: Queue<u8> = Queue::with_capacity(1);
	q.queue(1).unwrap();
	let _ = q.force_queue(2);
	assert_eq!(q.peek(), Some(2));
}

#[test]
fn force_queue_with_capacity_check_size() {
	let mut q = Queue::with_capacity(1);
	q.queue(1).unwrap();
	assert_eq!(1, q.force_queue(2));
}

#[test]
fn force_queue_no_capacity() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	assert_eq!(2, q.force_queue(2));
}

#[test]
fn no_len() {
	let q: Queue<u8> = Queue::new();
	assert_eq!(q.len(), 0);
}

#[test]
fn some_len() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	q.queue(2).unwrap();
	assert_eq!(q.len(), 2);
}

#[test]
fn is_empty_empty() {
	let q: Queue<i64> = Queue::new();
	assert_eq!(q.is_empty(), true);
}

#[test]
fn is_empty_some() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	assert_eq!(q.is_empty(), false);
}
<|endoftext|>


<commit_before>use super::gl_lib as gl;

pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}

pub struct Viewport {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32
}

impl Viewport {
    pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
        Viewport {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

bitflags! {
    flags BufferBits: gl::types::GLbitfield {
        const COLOR_BUFFER_BIT = gl::COLOR_BUFFER_BIT,
        const DEPTH_BUFFER_BIT = gl::DEPTH_BUFFER_BIT,
        const STENCIL_BUFFER_BIT = gl::STENCIL_BUFFER_BIT
    }
}

#[derive(Debug)]
pub enum GLError {
    Message(String)
}

#[derive(Debug, Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum DrawingMode {
    POINTS = gl::POINTS as isize,
    LINE_STRIP = gl::LINE_STRIP as isize,
    LINE_LOOP = gl::LINE_LOOP as isize,
    LINES = gl::LINES as isize,
    TRIANGLE_STRIP = gl::TRIANGLE_STRIP as isize,
    TRIANGLE_FAN = gl::TRIANGLE_FAN as isize,
    TRIANGLES = gl::TRIANGLES as isize
}
pub use self::DrawingMode::*;
<commit_msg>Add other variants to `GLError` representing all OpenGL error values<commit_after>use super::gl_lib as gl;

pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}

pub struct Viewport {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32
}

impl Viewport {
    pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
        Viewport {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

bitflags! {
    flags BufferBits: gl::types::GLbitfield {
        const COLOR_BUFFER_BIT = gl::COLOR_BUFFER_BIT,
        const DEPTH_BUFFER_BIT = gl::DEPTH_BUFFER_BIT,
        const STENCIL_BUFFER_BIT = gl::STENCIL_BUFFER_BIT
    }
}

#[derive(Debug)]
pub enum GLError {
    InvalidEnum,
    InvalidValue,
    InvalidOperation,
    InvalidFramebufferOperation,
    OutOfMemory,
    Message(String)
}

#[derive(Debug, Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum DrawingMode {
    POINTS = gl::POINTS as isize,
    LINE_STRIP = gl::LINE_STRIP as isize,
    LINE_LOOP = gl::LINE_LOOP as isize,
    LINES = gl::LINES as isize,
    TRIANGLE_STRIP = gl::TRIANGLE_STRIP as isize,
    TRIANGLE_FAN = gl::TRIANGLE_FAN as isize,
    TRIANGLES = gl::TRIANGLES as isize
}
pub use self::DrawingMode::*;
<|endoftext|>


<commit_before>use std::fmt;
use super::gl_lib as gl;

pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}

pub struct Viewport {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32
}

impl Viewport {
    pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
        Viewport {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

bitflags! {
    flags BufferBits: gl::types::GLbitfield {
        const COLOR_BUFFER_BIT = gl::COLOR_BUFFER_BIT,
        const DEPTH_BUFFER_BIT = gl::DEPTH_BUFFER_BIT,
        const STENCIL_BUFFER_BIT = gl::STENCIL_BUFFER_BIT
    }
}

#[derive(Debug)]
pub enum GLError {
    InvalidEnum,
    InvalidValue,
    InvalidOperation,
    InvalidFramebufferOperation,
    OutOfMemory,
    Message(String)
}

impl fmt::Display for GLError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GLError::InvalidEnum => {
                write!(f, "Invalid enum")
            },
            GLError::InvalidValue => {
                write!(f, "Invalid value")
            },
            GLError::InvalidOperation => {
                write!(f, "Invalid operation")
            },
            GLError::InvalidFramebufferOperation => {
                write!(f, "Invalid framebuffer operation")
            },
            GLError::OutOfMemory => {
                write!(f, "Out of memory")
            },
            GLError::Message(ref s) => {
                write!(f, "{}", s)
            }
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum DrawingMode {
    POINTS = gl::POINTS as isize,
    LINE_STRIP = gl::LINE_STRIP as isize,
    LINE_LOOP = gl::LINE_LOOP as isize,
    LINES = gl::LINES as isize,
    TRIANGLE_STRIP = gl::TRIANGLE_STRIP as isize,
    TRIANGLE_FAN = gl::TRIANGLE_FAN as isize,
    TRIANGLES = gl::TRIANGLES as isize
}
pub use self::DrawingMode::*;
<commit_msg>Impl` std::error::Error` for `GLError`<commit_after>use std::fmt;
use std::error;
use super::gl_lib as gl;

pub struct Color {
    pub r: f32,
    pub g: f32,
    pub b: f32,
    pub a: f32
}

impl Color {
    pub fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
        Color { r: r, g: g, b: b, a: a}
    }
}

pub struct Viewport {
    pub x: u32,
    pub y: u32,
    pub width: u32,
    pub height: u32
}

impl Viewport {
    pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
        Viewport {
            x: x,
            y: y,
            width: width,
            height: height
        }
    }
}

bitflags! {
    flags BufferBits: gl::types::GLbitfield {
        const COLOR_BUFFER_BIT = gl::COLOR_BUFFER_BIT,
        const DEPTH_BUFFER_BIT = gl::DEPTH_BUFFER_BIT,
        const STENCIL_BUFFER_BIT = gl::STENCIL_BUFFER_BIT
    }
}

#[derive(Debug)]
pub enum GLError {
    InvalidEnum,
    InvalidValue,
    InvalidOperation,
    InvalidFramebufferOperation,
    OutOfMemory,
    Message(String)
}

impl fmt::Display for GLError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            GLError::InvalidEnum => {
                write!(f, "Invalid enum")
            },
            GLError::InvalidValue => {
                write!(f, "Invalid value")
            },
            GLError::InvalidOperation => {
                write!(f, "Invalid operation")
            },
            GLError::InvalidFramebufferOperation => {
                write!(f, "Invalid framebuffer operation")
            },
            GLError::OutOfMemory => {
                write!(f, "Out of memory")
            },
            GLError::Message(ref s) => {
                write!(f, "{}", s)
            }
        }
    }
}

impl error::Error for GLError {
    fn description(&self) -> &str {
        match *self {
            GLError::InvalidEnum => "Invalid enum variant in OpenGL call.",
            GLError::InvalidValue => "Out-of-range value in OpenGL call.",
            GLError::InvalidOperation => "The specified OpenGL operation is not allowed in the current state.",
            GLError::InvalidFramebufferOperation => "OpenGL command tried to read or write to an incomplete framebuffer.",
            GLError::OutOfMemory => "There is not enough memory left to execute the specified OpenGL command.",
            GLError::Message(ref s) => &s
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum DrawingMode {
    POINTS = gl::POINTS as isize,
    LINE_STRIP = gl::LINE_STRIP as isize,
    LINE_LOOP = gl::LINE_LOOP as isize,
    LINES = gl::LINES as isize,
    TRIANGLE_STRIP = gl::TRIANGLE_STRIP as isize,
    TRIANGLE_FAN = gl::TRIANGLE_FAN as isize,
    TRIANGLES = gl::TRIANGLES as isize
}
pub use self::DrawingMode::*;
<|endoftext|>