<commit_before>//! Metamethods for accesssing the registry values!

use super::super::super::registry;

use hlua::{LuaTable};
use hlua::any::AnyLuaValue;

use rustc_serialize::json::{Json, ToJson};
use std::ops::Deref;
pub fn index(table: AnyLuaValue, lua_key: AnyLuaValue) -> Result<AnyLuaValue, &'static str> {
    if let AnyLuaValue::LuaString(key) = lua_key {
        let maybe_json = registry::get_json(&key);
        if let Some(json) = maybe_json {
            Ok(convert_json(json.deref().to_json()))
        }
        else {
            Err("No value found for that key!")
        }
    }
    else {
        Err("The registry can only be indexed with keys!")
    }
}

// Prevent lua from changing the registry?
pub fn new_index(table: AnyLuaValue, key: AnyLuaValue, val: AnyLuaValue)
                 -> Result<(), &'static str> {
    Err("You can't set the registry!")
}

fn convert_json(json: Json) -> AnyLuaValue {
    match json {
        Json::String(val) => AnyLuaValue::LuaString(val),
        Json::Boolean(val) => AnyLuaValue::LuaBoolean(val),
        Json::F64(val) => AnyLuaValue::LuaNumber(val),
        Json::I64(val) => AnyLuaValue::LuaNumber((val as i32) as f64),
        Json::U64(val) => AnyLuaValue::LuaNumber((val as u32) as f64),
        Json::Null => AnyLuaValue::LuaString("nil".to_string()),
        Json::Array(mut vals) => {
            let mut count = 0f64;
            // Gotta love that 1-based indexing. Start at zero but increment for
            // the first one. It works here at least.
            AnyLuaValue::LuaArray(vals.into_iter().map(|v| {
                count += 1.0;
                (AnyLuaValue::LuaNumber(count), convert_json(v))
            }).collect())
        },
        Json::Object(mut vals) => {
            AnyLuaValue::LuaArray(vals.into_iter().map(|(key, val)| {
                (AnyLuaValue::LuaString(key), convert_json(val))
            }).collect())
        }
    }
}
<commit_msg>Add tests for lua registry convert_json function<commit_after>//! Metamethods for accesssing the registry values!

use super::super::super::registry;

use hlua::{LuaTable};
use hlua::any::AnyLuaValue;

use rustc_serialize::json::{Json, ToJson};
use std::ops::Deref;
pub fn index(table: AnyLuaValue, lua_key: AnyLuaValue) -> Result<AnyLuaValue, &'static str> {
    if let AnyLuaValue::LuaString(key) = lua_key {
        let maybe_json = registry::get_json(&key);
        if let Some(json) = maybe_json {
            Ok(convert_json(json.deref().to_json()))
        }
        else {
            Err("No value found for that key!")
        }
    }
    else {
        Err("The registry can only be indexed with keys!")
    }
}

// Prevent lua from changing the registry?
pub fn new_index(table: AnyLuaValue, key: AnyLuaValue, val: AnyLuaValue)
                 -> Result<(), &'static str> {
    Err("You can't set the registry!")
}

fn convert_json(json: Json) -> AnyLuaValue {
    match json {
        Json::String(val) => AnyLuaValue::LuaString(val),
        Json::Boolean(val) => AnyLuaValue::LuaBoolean(val),
        Json::F64(val) => AnyLuaValue::LuaNumber(val),
        Json::I64(val) => AnyLuaValue::LuaNumber((val as i32) as f64),
        Json::U64(val) => AnyLuaValue::LuaNumber((val as u32) as f64),
        Json::Null => AnyLuaValue::LuaString("none".to_string()),
        Json::Array(mut vals) => {
            let mut count = 0f64;
            // Gotta love that 1-based indexing. Start at zero but increment for
            // the first one. It works here at least.
            AnyLuaValue::LuaArray(vals.into_iter().map(|v| {
                count += 1.0;
                (AnyLuaValue::LuaNumber(count), convert_json(v))
            }).collect())
        },
        Json::Object(mut vals) => {
            AnyLuaValue::LuaArray(vals.into_iter().map(|(key, val)| {
                (AnyLuaValue::LuaString(key), convert_json(val))
            }).collect())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::convert_json;
    use hlua::any::AnyLuaValue::*;
    use rustc_serialize::json::{Json, ToJson, Object};
    use std::collections::BTreeMap;

    #[test]
    fn convert_string() {
        let input = "Hello World".to_string();
        let json_input = Json::String(input.clone());
        assert_eq!(convert_json(json_input), LuaString(input));
    }
    #[test]
    fn convert_numbers() {
        let lua_number = LuaNumber(42f64);
        assert_eq!(convert_json(Json::F64(42f64)), lua_number);
        assert_eq!(convert_json(Json::I64(42i64)), lua_number);
        assert_eq!(convert_json(Json::U64(42u64)), lua_number);
    }

    #[test]
    fn convert_bool() {
        assert_eq!(convert_json(Json::Boolean(true)), LuaBoolean(true));
        assert_eq!(convert_json(Json::Boolean(false)), LuaBoolean(false));
    }

    #[test]
    fn convert_array() {
        let json = Json::Array(
            vec![Json::Boolean(true), Json::F64(11f64),
                 Json::String("Foo".to_string())]
        );
        let lua = LuaArray(vec![
                (LuaNumber(1f64), LuaBoolean(true)),
                (LuaNumber(2f64), LuaNumber(11f64)),
                (LuaNumber(3f64), LuaString("Foo".to_string()))
            ]);
        assert_eq!(convert_json(json), lua);
    }

    #[test]
    fn convert_object() {
        // { name="foo", point: {x=0, y=1}, valid=false }
        // The fields are emitted in alphabetical order thanks to Json's
        // internal BTreeMap representation.

        let mut json_tree: Object = BTreeMap::new();
        let mut point_tree: Object = BTreeMap::new();
        point_tree.insert("x".to_string(), Json::U64(0u64));
        point_tree.insert("y".to_string(), Json::U64(1u64));
        json_tree.insert("point".to_string(), Json::Object(point_tree));
        json_tree.insert("name".to_string(), Json::String("foo".to_string()));
        json_tree.insert("valid".to_string(), Json::Boolean(false));

        let lua = LuaArray(vec![
            (LuaString("name".to_string()), LuaString("foo".to_string())),
            (LuaString("point".to_string()), LuaArray(vec![
                (LuaString("x".to_string()), LuaNumber(0f64)),
                (LuaString("y".to_string()), LuaNumber(1f64))
            ])),
            (LuaString("valid".to_string()), LuaBoolean(false)),
        ]);

        assert_eq!(convert_json(Json::Object(json_tree)), lua);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

// This example demonstrates how to use pipeline caching.
//
// Using a PipelineCache can improve performance significantly,
// by checking if the requested pipeline exists in the cache and if so,
// return that pipeline directly or insert that new pipeline into the
// cache.
//
// You can retrieve the data in the cache as a `Vec<u8>` and
// save that to a binary file. Later you can load that file and build a
// PipelineCache with the given data. Be aware that the Vulkan
// implementation does not check if the data is valid and vulkano
// currently does not either. Invalid data can lead to driver crashes
// or worse. Using the same cache data with a different GPU probably
// won't work, a simple driver update can lead to invalid data as well.
// To check if your data is valid you can find inspiration here:
//      https://zeux.io/2019/07/17/serializing-pipeline-cache/
//
// In the future, vulkano might implement those safety checks, but for
// now, you would have to do that yourself or trust the data and the user.

use std::fs;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::sync::Arc;

use vulkano::device::{Device, DeviceExtensions};
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::pipeline::cache::PipelineCache;
use vulkano::pipeline::ComputePipeline;

fn main() {
    // As with other examples, the first step is to create an instance.
    let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();

    // Choose which physical device to use.
    let physical = PhysicalDevice::enumerate(&instance).next().unwrap();

    // Choose the queue of the physical device which is going to run our compute operation.
    //
    // The Vulkan specs guarantee that a compliant implementation must provide at least one queue
    // that supports compute operations.
    let queue_family = physical
        .queue_families()
        .find(|&q| q.supports_compute())
        .unwrap();

    // Now initializing the device.
    let (device, _) = Device::new(
        physical,
        physical.supported_features(),
        &DeviceExtensions {
            khr_storage_buffer_storage_class: true,
            ..DeviceExtensions::none()
        },
        [(queue_family, 0.5)].iter().cloned(),
    )
    .unwrap();

    println!("Device initialized");

    // We are creating an empty PipelineCache to start somewhere.
    let pipeline_cache = PipelineCache::empty(device.clone()).unwrap();

    // We need to create the compute pipeline that describes our operation. We are using the
    // shader from the basic-compute-shader example.
    //
    // If you are familiar with graphics pipeline, the principle is the same except that compute
    // pipelines are much simpler to create.
    //
    // Pass the PipelineCache as an optional parameter to the ComputePipeline constructor.
    // For GraphicPipelines you can use the GraphicPipelineBuilder that has a method
    // `build_with_cache(cache: Arc<PipelineCache>)`
    let pipeline = Arc::new({
        mod cs {
            vulkano_shaders::shader! {
                ty: "compute",
                src: "
                    #version 450

                    layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;

                    layout(set = 0, binding = 0) buffer Data {
                        uint data[];
                    } data;

                    void main() {
                        uint idx = gl_GlobalInvocationID.x;
                        data.data[idx] *= 12;
                    }
                "
            }
        }
        let shader = cs::Shader::load(device.clone()).unwrap();
        ComputePipeline::new(
            device.clone(),
            &shader.main_entry_point(),
            &(),
            Some(pipeline_cache.clone()),
        )
        .unwrap()
    });

    // Normally you would use your pipeline for computing, but we just want to focus on the
    // cache functionality.
    // The cache works the same for a GraphicsPipeline, a ComputePipeline is just simpler to
    // build.
    //
    // We are now going to retrieve the cache data into a Vec<u8> and save that to a file on
    // our disk.

    if let Ok(data) = pipeline_cache.get_data() {
        if let Ok(mut file) = File::create("pipeline_cache.bin.tmp") {
            if let Ok(_) = file.write_all(&data) {
                let _ = fs::rename("pipeline_cache.bin.tmp", "pipeline_cache.bin");
            } else {
                let _ = fs::remove_file("pipeline_cache.bin.tmp");
            }
        }
    }

    // The PipelineCache is now saved to disk and can be loaded the next time the application
    // is started. This way, the pipelines do not have to be rebuild and pipelines that might
    // exist in the cache can be build far quicker.
    //
    // To load the cache from the file, we just need to load the data into a Vec<u8> and build
    // the PipelineCache from that. Note that this function is currently unsafe as there are
    // no checks, as it was mentioned at the start of this example.
    let data = {
        if let Ok(mut file) = File::open("pipeline_cache.bin") {
            let mut data = Vec::new();
            if let Ok(_) = file.read_to_end(&mut data) {
                Some(data)
            } else {
                None
            }
        } else {
            None
        }
    };

    let second_cache = if let Some(data) = data {
        // This is unsafe because there is no way to be sure that the file contains valid data.
        unsafe { PipelineCache::with_data(device.clone(), &data).unwrap() }
    } else {
        PipelineCache::empty(device.clone()).unwrap()
    };

    // As the PipelineCache of the Vulkan implementation saves an opaque blob of data,
    // there is no real way to know if the data is correct. There might be differences
    // in the byte blob here, but it should still work.
    // If it doesn't, please check if there is an issue describing this problem, and if
    // not open a new one, on the GitHub page.
    println!("first : {:?}", pipeline_cache.get_data().unwrap());
    println!("second: {:?}", second_cache.get_data().unwrap());
}
<commit_msg>examples: bin; pipeline_caching, add underscore for unused var (#1448)<commit_after>// Copyright (c) 2017 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

// This example demonstrates how to use pipeline caching.
//
// Using a PipelineCache can improve performance significantly,
// by checking if the requested pipeline exists in the cache and if so,
// return that pipeline directly or insert that new pipeline into the
// cache.
//
// You can retrieve the data in the cache as a `Vec<u8>` and
// save that to a binary file. Later you can load that file and build a
// PipelineCache with the given data. Be aware that the Vulkan
// implementation does not check if the data is valid and vulkano
// currently does not either. Invalid data can lead to driver crashes
// or worse. Using the same cache data with a different GPU probably
// won't work, a simple driver update can lead to invalid data as well.
// To check if your data is valid you can find inspiration here:
//      https://zeux.io/2019/07/17/serializing-pipeline-cache/
//
// In the future, vulkano might implement those safety checks, but for
// now, you would have to do that yourself or trust the data and the user.

use std::fs;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::sync::Arc;

use vulkano::device::{Device, DeviceExtensions};
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::pipeline::cache::PipelineCache;
use vulkano::pipeline::ComputePipeline;

fn main() {
    // As with other examples, the first step is to create an instance.
    let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();

    // Choose which physical device to use.
    let physical = PhysicalDevice::enumerate(&instance).next().unwrap();

    // Choose the queue of the physical device which is going to run our compute operation.
    //
    // The Vulkan specs guarantee that a compliant implementation must provide at least one queue
    // that supports compute operations.
    let queue_family = physical
        .queue_families()
        .find(|&q| q.supports_compute())
        .unwrap();

    // Now initializing the device.
    let (device, _) = Device::new(
        physical,
        physical.supported_features(),
        &DeviceExtensions {
            khr_storage_buffer_storage_class: true,
            ..DeviceExtensions::none()
        },
        [(queue_family, 0.5)].iter().cloned(),
    )
    .unwrap();

    println!("Device initialized");

    // We are creating an empty PipelineCache to start somewhere.
    let pipeline_cache = PipelineCache::empty(device.clone()).unwrap();

    // We need to create the compute pipeline that describes our operation. We are using the
    // shader from the basic-compute-shader example.
    //
    // If you are familiar with graphics pipeline, the principle is the same except that compute
    // pipelines are much simpler to create.
    //
    // Pass the PipelineCache as an optional parameter to the ComputePipeline constructor.
    // For GraphicPipelines you can use the GraphicPipelineBuilder that has a method
    // `build_with_cache(cache: Arc<PipelineCache>)`
    let _pipeline = Arc::new({
        mod cs {
            vulkano_shaders::shader! {
                ty: "compute",
                src: "
                    #version 450

                    layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;

                    layout(set = 0, binding = 0) buffer Data {
                        uint data[];
                    } data;

                    void main() {
                        uint idx = gl_GlobalInvocationID.x;
                        data.data[idx] *= 12;
                    }
                "
            }
        }
        let shader = cs::Shader::load(device.clone()).unwrap();
        ComputePipeline::new(
            device.clone(),
            &shader.main_entry_point(),
            &(),
            Some(pipeline_cache.clone()),
        )
        .unwrap()
    });

    // Normally you would use your pipeline for computing, but we just want to focus on the
    // cache functionality.
    // The cache works the same for a GraphicsPipeline, a ComputePipeline is just simpler to
    // build.
    //
    // We are now going to retrieve the cache data into a Vec<u8> and save that to a file on
    // our disk.

    if let Ok(data) = pipeline_cache.get_data() {
        if let Ok(mut file) = File::create("pipeline_cache.bin.tmp") {
            if let Ok(_) = file.write_all(&data) {
                let _ = fs::rename("pipeline_cache.bin.tmp", "pipeline_cache.bin");
            } else {
                let _ = fs::remove_file("pipeline_cache.bin.tmp");
            }
        }
    }

    // The PipelineCache is now saved to disk and can be loaded the next time the application
    // is started. This way, the pipelines do not have to be rebuild and pipelines that might
    // exist in the cache can be build far quicker.
    //
    // To load the cache from the file, we just need to load the data into a Vec<u8> and build
    // the PipelineCache from that. Note that this function is currently unsafe as there are
    // no checks, as it was mentioned at the start of this example.
    let data = {
        if let Ok(mut file) = File::open("pipeline_cache.bin") {
            let mut data = Vec::new();
            if let Ok(_) = file.read_to_end(&mut data) {
                Some(data)
            } else {
                None
            }
        } else {
            None
        }
    };

    let second_cache = if let Some(data) = data {
        // This is unsafe because there is no way to be sure that the file contains valid data.
        unsafe { PipelineCache::with_data(device.clone(), &data).unwrap() }
    } else {
        PipelineCache::empty(device.clone()).unwrap()
    };

    // As the PipelineCache of the Vulkan implementation saves an opaque blob of data,
    // there is no real way to know if the data is correct. There might be differences
    // in the byte blob here, but it should still work.
    // If it doesn't, please check if there is an issue describing this problem, and if
    // not open a new one, on the GitHub page.
    println!("first : {:?}", pipeline_cache.get_data().unwrap());
    println!("second: {:?}", second_cache.get_data().unwrap());
}
<|endoftext|>


<commit_before>// Copyright 2017 Serde Developers
//
// 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.

use serde::{ser, Serialize};

use error::Error;
use token::Token;

/// A `Serializer` that ensures that a value serializes to a given list of tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
    tokens: &'a [Token],
}

impl<'a> Serializer<'a> {
    /// Creates the serializer.
    pub fn new(tokens: &'a [Token]) -> Self {
        Serializer { tokens: tokens }
    }

    /// Pulls the next token off of the serializer, ignoring it.
    fn next_token(&mut self) -> Option<Token> {
        if let Some((&first, rest)) = self.tokens.split_first() {
            self.tokens = rest;
            Some(first)
        } else {
            None
        }
    }

    pub fn remaining(&self) -> usize {
        self.tokens.len()
    }
}

macro_rules! assert_next_token {
    ($ser:expr, $expected:ident) => {
        assert_next_token!($ser, $expected, Token::$expected, true);
    };
    ($ser:expr, $expected:ident($v:expr)) => {
        assert_next_token!($ser, $expected, Token::$expected(v), v == $v);
    };
    ($ser:expr, $expected:ident { $($k:ident),* }) => {
        let compare = ($($k,)*);
        assert_next_token!($ser, $expected, Token::$expected { $($k),* }, ($($k,)*) == compare);
    };
    ($ser:expr, $expected:ident, $pat:pat, $guard:expr) => {
        match $ser.next_token() {
            Some($pat) if $guard => {}
            Some(other) => {
                panic!("expected Token::{} but serialized as {}",
                       stringify!($expected), other);
            }
            None => {
                panic!("expected Token::{} after end of serialized tokens",
                       stringify!($expected));
            }
        }
    };
}

impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Self;
    type SerializeTuple = Self;
    type SerializeTupleStruct = Self;
    type SerializeTupleVariant = Variant<'s, 'a>;
    type SerializeMap = Self;
    type SerializeStruct = Self;
    type SerializeStructVariant = Variant<'s, 'a>;

    fn serialize_bool(self, v: bool) -> Result<(), Error> {
        assert_next_token!(self, Bool(v));
        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<(), Error> {
        assert_next_token!(self, I8(v));
        Ok(())
    }

    fn serialize_i16(self, v: i16) -> Result<(), Error> {
        assert_next_token!(self, I16(v));
        Ok(())
    }

    fn serialize_i32(self, v: i32) -> Result<(), Error> {
        assert_next_token!(self, I32(v));
        Ok(())
    }

    fn serialize_i64(self, v: i64) -> Result<(), Error> {
        assert_next_token!(self, I64(v));
        Ok(())
    }

    fn serialize_u8(self, v: u8) -> Result<(), Error> {
        assert_next_token!(self, U8(v));
        Ok(())
    }

    fn serialize_u16(self, v: u16) -> Result<(), Error> {
        assert_next_token!(self, U16(v));
        Ok(())
    }

    fn serialize_u32(self, v: u32) -> Result<(), Error> {
        assert_next_token!(self, U32(v));
        Ok(())
    }

    fn serialize_u64(self, v: u64) -> Result<(), Error> {
        assert_next_token!(self, U64(v));
        Ok(())
    }

    fn serialize_f32(self, v: f32) -> Result<(), Error> {
        assert_next_token!(self, F32(v));
        Ok(())
    }

    fn serialize_f64(self, v: f64) -> Result<(), Error> {
        assert_next_token!(self, F64(v));
        Ok(())
    }

    fn serialize_char(self, v: char) -> Result<(), Error> {
        assert_next_token!(self, Char(v));
        Ok(())
    }

    fn serialize_str(self, v: &str) -> Result<(), Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedStr(_)) => assert_next_token!(self, BorrowedStr(v)),
            Some(&Token::String(_)) => assert_next_token!(self, String(v)),
            _ => assert_next_token!(self, Str(v)),
        }
        Ok(())
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedBytes(_)) => assert_next_token!(self, BorrowedBytes(v)),
            Some(&Token::ByteBuf(_)) => assert_next_token!(self, ByteBuf(v)),
            _ => assert_next_token!(self, Bytes(v)),
        }
        Ok(())
    }

    fn serialize_unit(self) -> Result<(), Error> {
        assert_next_token!(self, Unit);
        Ok(())
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> {
        assert_next_token!(self, UnitStruct { name });
        Ok(())
    }

    fn serialize_unit_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
    ) -> Result<(), Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            assert_next_token!(self, Unit);
        } else {
            assert_next_token!(self, UnitVariant { name, variant });
        }
        Ok(())
    }

    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, NewtypeStruct { name });
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        value: &T,
    ) -> Result<(), Error>
    where
        T: Serialize,
    {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
        } else {
            assert_next_token!(self, NewtypeVariant { name, variant });
        }
        value.serialize(self)
    }

    fn serialize_none(self) -> Result<(), Error> {
        assert_next_token!(self, None);
        Ok(())
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, Some);
        value.serialize(self)
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Seq { len });
        Ok(self)
    }

    fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Tuple { len });
        Ok(self)
    }

    fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, TupleStruct { name, len });
        Ok(self)
    }

    fn serialize_tuple_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Seq { len });
            Ok(Variant {
                ser: self,
                end: Token::SeqEnd,
            })
        } else {
            assert_next_token!(self, TupleVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::TupleVariantEnd,
            })
        }
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Map { len });
        Ok(self)
    }

    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Struct { name, len });
        Ok(self)
    }

    fn serialize_struct_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStructVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Map { len });
            Ok(Variant {
                ser: self,
                end: Token::MapEnd,
            })
        } else {
            assert_next_token!(self, StructVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::StructVariantEnd,
            })
        }
    }

    fn is_human_readable(&self) -> bool {
        panic!(
            "Types which have different human-readable and compact representations\
             must explicitly mark their test cases with `serde_test::Configure`"
        );
    }
}

pub struct Variant<'s, 'a: 's> {
    ser: &'s mut Serializer<'a>,
    end: Token,
}

impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, SeqEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleStructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Error> {
        match self.end {
            Token::TupleVariantEnd => assert_next_token!(self.ser, TupleVariantEnd),
            Token::SeqEnd => assert_next_token!(self.ser, SeqEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut **self)
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, MapEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        try!(key.serialize(&mut **self));
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, StructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStructVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        try!(key.serialize(&mut *self.ser));
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Self::Error> {
        match self.end {
            Token::StructVariantEnd => assert_next_token!(self.ser, StructVariantEnd),
            Token::MapEnd => assert_next_token!(self.ser, MapEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}
<commit_msg>Print the contents of the expected token when a serialize assert fails<commit_after>// Copyright 2017 Serde Developers
//
// 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.

use serde::{ser, Serialize};

use error::Error;
use token::Token;

/// A `Serializer` that ensures that a value serializes to a given list of tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
    tokens: &'a [Token],
}

impl<'a> Serializer<'a> {
    /// Creates the serializer.
    pub fn new(tokens: &'a [Token]) -> Self {
        Serializer { tokens: tokens }
    }

    /// Pulls the next token off of the serializer, ignoring it.
    fn next_token(&mut self) -> Option<Token> {
        if let Some((&first, rest)) = self.tokens.split_first() {
            self.tokens = rest;
            Some(first)
        } else {
            None
        }
    }

    pub fn remaining(&self) -> usize {
        self.tokens.len()
    }
}

macro_rules! assert_next_token {
    ($ser:expr, $expected:ident) => {
        assert_next_token!($ser, stringify!($expected), Token::$expected, true);
    };
    ($ser:expr, $expected:ident($v:expr)) => {
        assert_next_token!(
            $ser,
            format_args!("{}({:?})", stringify!($expected), $v),
            Token::$expected(v),
            v == $v
        );
    };
    ($ser:expr, $expected:ident { $($k:ident),* }) => {
        let compare = ($($k,)*);
        let field_format = || {
            use std::fmt::Write;
            let mut buffer = String::new();
            $(
                write!(&mut buffer, "{}: {:?}, ", stringify!($k), $k).unwrap();
            )*
            buffer
        };
        assert_next_token!(
            $ser,
            format_args!("{} {{ {}}}", stringify!($expected), field_format()),
            Token::$expected { $($k),* },
            ($($k,)*) == compare
        );
    };
    ($ser:expr, $expected:expr, $pat:pat, $guard:expr) => {
        match $ser.next_token() {
            Some($pat) if $guard => {}
            Some(other) => {
                panic!("expected Token::{} but serialized as {}",
                       $expected, other);
            }
            None => {
                panic!("expected Token::{} after end of serialized tokens",
                       $expected);
            }
        }
    };
}

impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Self;
    type SerializeTuple = Self;
    type SerializeTupleStruct = Self;
    type SerializeTupleVariant = Variant<'s, 'a>;
    type SerializeMap = Self;
    type SerializeStruct = Self;
    type SerializeStructVariant = Variant<'s, 'a>;

    fn serialize_bool(self, v: bool) -> Result<(), Error> {
        assert_next_token!(self, Bool(v));
        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<(), Error> {
        assert_next_token!(self, I8(v));
        Ok(())
    }

    fn serialize_i16(self, v: i16) -> Result<(), Error> {
        assert_next_token!(self, I16(v));
        Ok(())
    }

    fn serialize_i32(self, v: i32) -> Result<(), Error> {
        assert_next_token!(self, I32(v));
        Ok(())
    }

    fn serialize_i64(self, v: i64) -> Result<(), Error> {
        assert_next_token!(self, I64(v));
        Ok(())
    }

    fn serialize_u8(self, v: u8) -> Result<(), Error> {
        assert_next_token!(self, U8(v));
        Ok(())
    }

    fn serialize_u16(self, v: u16) -> Result<(), Error> {
        assert_next_token!(self, U16(v));
        Ok(())
    }

    fn serialize_u32(self, v: u32) -> Result<(), Error> {
        assert_next_token!(self, U32(v));
        Ok(())
    }

    fn serialize_u64(self, v: u64) -> Result<(), Error> {
        assert_next_token!(self, U64(v));
        Ok(())
    }

    fn serialize_f32(self, v: f32) -> Result<(), Error> {
        assert_next_token!(self, F32(v));
        Ok(())
    }

    fn serialize_f64(self, v: f64) -> Result<(), Error> {
        assert_next_token!(self, F64(v));
        Ok(())
    }

    fn serialize_char(self, v: char) -> Result<(), Error> {
        assert_next_token!(self, Char(v));
        Ok(())
    }

    fn serialize_str(self, v: &str) -> Result<(), Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedStr(_)) => assert_next_token!(self, BorrowedStr(v)),
            Some(&Token::String(_)) => assert_next_token!(self, String(v)),
            _ => assert_next_token!(self, Str(v)),
        }
        Ok(())
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedBytes(_)) => assert_next_token!(self, BorrowedBytes(v)),
            Some(&Token::ByteBuf(_)) => assert_next_token!(self, ByteBuf(v)),
            _ => assert_next_token!(self, Bytes(v)),
        }
        Ok(())
    }

    fn serialize_unit(self) -> Result<(), Error> {
        assert_next_token!(self, Unit);
        Ok(())
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> {
        assert_next_token!(self, UnitStruct { name });
        Ok(())
    }

    fn serialize_unit_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
    ) -> Result<(), Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            assert_next_token!(self, Unit);
        } else {
            assert_next_token!(self, UnitVariant { name, variant });
        }
        Ok(())
    }

    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, NewtypeStruct { name });
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        value: &T,
    ) -> Result<(), Error>
    where
        T: Serialize,
    {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
        } else {
            assert_next_token!(self, NewtypeVariant { name, variant });
        }
        value.serialize(self)
    }

    fn serialize_none(self) -> Result<(), Error> {
        assert_next_token!(self, None);
        Ok(())
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, Some);
        value.serialize(self)
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Seq { len });
        Ok(self)
    }

    fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Tuple { len });
        Ok(self)
    }

    fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, TupleStruct { name, len });
        Ok(self)
    }

    fn serialize_tuple_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Seq { len });
            Ok(Variant {
                ser: self,
                end: Token::SeqEnd,
            })
        } else {
            assert_next_token!(self, TupleVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::TupleVariantEnd,
            })
        }
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Map { len });
        Ok(self)
    }

    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Struct { name, len });
        Ok(self)
    }

    fn serialize_struct_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStructVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Map { len });
            Ok(Variant {
                ser: self,
                end: Token::MapEnd,
            })
        } else {
            assert_next_token!(self, StructVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::StructVariantEnd,
            })
        }
    }

    fn is_human_readable(&self) -> bool {
        panic!(
            "Types which have different human-readable and compact representations\
             must explicitly mark their test cases with `serde_test::Configure`"
        );
    }
}

pub struct Variant<'s, 'a: 's> {
    ser: &'s mut Serializer<'a>,
    end: Token,
}

impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, SeqEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleStructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Error> {
        match self.end {
            Token::TupleVariantEnd => assert_next_token!(self.ser, TupleVariantEnd),
            Token::SeqEnd => assert_next_token!(self.ser, SeqEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut **self)
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, MapEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        try!(key.serialize(&mut **self));
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, StructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStructVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        try!(key.serialize(&mut *self.ser));
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Self::Error> {
        match self.end {
            Token::StructVariantEnd => assert_next_token!(self.ser, StructVariantEnd),
            Token::MapEnd => assert_next_token!(self.ser, MapEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::marker::Unpin;
use crate::ops;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// A future represents an asynchronous computation.
///
/// A future is a value that may not have finished computing yet. This kind of
/// "asynchronous value" makes it possible for a thread to continue doing useful
/// work while it waits for the value to become available.
///
/// # The `poll` method
///
/// The core method of future, `poll`, *attempts* to resolve the future into a
/// final value. This method does not block if the value is not ready. Instead,
/// the current task is scheduled to be woken up when it's possible to make
/// further progress by `poll`ing again. The `context` passed to the `poll`
/// method can provide a `Waker`, which is a handle for waking up the current
/// task.
///
/// When using a future, you generally won't call `poll` directly, but instead
/// `await!` the value.
#[doc(spotlight)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")]
pub trait Future {
    /// The type of value produced on completion.
    #[stable(feature = "futures_api", since = "1.36.0")]
    type Output;

    /// Attempt to resolve the future to a final value, registering
    /// the current task for wakeup if the value is not yet available.
    ///
    /// # Return value
    ///
    /// This function returns:
    ///
    /// - [`Poll::Pending`] if the future is not ready yet
    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
    ///   finished successfully.
    ///
    /// Once a future has finished, clients should not `poll` it again.
    ///
    /// When a future is not ready yet, `poll` returns `Poll::Pending` and
    /// stores a clone of the [`Waker`] copied from the current [`Context`].
    /// This [`Waker`] is then woken once the future can make progress.
    /// For example, a future waiting for a socket to become
    /// readable would call `.clone()` on the [`Waker`] and store it.
    /// When a signal arrives elsewhere indicating that the socket is readable,
    /// [`Waker::wake`] is called and the socket future's task is awoken.
    /// Once a task has been woken up, it should attempt to `poll` the future
    /// again, which may or may not produce a final value.
    ///
    /// Note that on multiple calls to `poll`, only the [`Waker`] from the
    /// [`Context`] passed to the most recent call should be scheduled to
    /// receive a wakeup.
    ///
    /// # Runtime characteristics
    ///
    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
    /// progress, meaning that each time the current task is woken up, it should
    /// actively re-`poll` pending futures that it still has an interest in.
    ///
    /// The `poll` function is not called repeatedly in a tight loop -- instead,
    /// it should only be called when the future indicates that it is ready to
    /// make progress (by calling `wake()`). If you're familiar with the
    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
    /// typically do *not* suffer the same problems of "all wakeups must poll
    /// all events"; they are more like `epoll(4)`.
    ///
    /// An implementation of `poll` should strive to return quickly, and should
    /// not block. Returning quickly prevents unnecessarily clogging up
    /// threads or event loops. If it is known ahead of time that a call to
    /// `poll` may end up taking awhile, the work should be offloaded to a
    /// thread pool (or something similar) to ensure that `poll` can return
    /// quickly.
    ///
    /// # Panics
    ///
    /// Once a future has completed (returned `Ready` from `poll`), calling its
    /// `poll` method again may panic, block forever, or cause other kinds of
    /// problems; the `Future` trait places no requirements on the effects of
    /// such a call. However, as the `poll` method is not marked `unsafe`,
    /// Rust's usual rules apply: calls must never cause undefined behavior
    /// (memory corruption, incorrect use of `unsafe` functions, or the like),
    /// regardless of the future's state.
    ///
    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
    /// [`Context`]: ../task/struct.Context.html
    /// [`Waker`]: ../task/struct.Waker.html
    /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
    #[stable(feature = "futures_api", since = "1.36.0")]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: ?Sized + Future + Unpin> Future for &mut F {
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        F::poll(Pin::new(&mut **self), cx)
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl
 Future for Pin

where
    P: Unpin + ops::DerefMut,
    P::Target: Future,
{
    type Output = <
::Target as Future>::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        Pin::get_mut(self).as_mut().poll(cx)
    }
}
<commit_msg>Rollup merge of #61227 - diwic:patch-2, r=Centril<commit_after>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::marker::Unpin;
use crate::ops;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// A future represents an asynchronous computation.
///
/// A future is a value that may not have finished computing yet. This kind of
/// "asynchronous value" makes it possible for a thread to continue doing useful
/// work while it waits for the value to become available.
///
/// # The `poll` method
///
/// The core method of future, `poll`, *attempts* to resolve the future into a
/// final value. This method does not block if the value is not ready. Instead,
/// the current task is scheduled to be woken up when it's possible to make
/// further progress by `poll`ing again. The `context` passed to the `poll`
/// method can provide a `Waker`, which is a handle for waking up the current
/// task.
///
/// When using a future, you generally won't call `poll` directly, but instead
/// `.await` the value.
#[doc(spotlight)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")]
pub trait Future {
    /// The type of value produced on completion.
    #[stable(feature = "futures_api", since = "1.36.0")]
    type Output;

    /// Attempt to resolve the future to a final value, registering
    /// the current task for wakeup if the value is not yet available.
    ///
    /// # Return value
    ///
    /// This function returns:
    ///
    /// - [`Poll::Pending`] if the future is not ready yet
    /// - [`Poll::Ready(val)`] with the result `val` of this future if it
    ///   finished successfully.
    ///
    /// Once a future has finished, clients should not `poll` it again.
    ///
    /// When a future is not ready yet, `poll` returns `Poll::Pending` and
    /// stores a clone of the [`Waker`] copied from the current [`Context`].
    /// This [`Waker`] is then woken once the future can make progress.
    /// For example, a future waiting for a socket to become
    /// readable would call `.clone()` on the [`Waker`] and store it.
    /// When a signal arrives elsewhere indicating that the socket is readable,
    /// [`Waker::wake`] is called and the socket future's task is awoken.
    /// Once a task has been woken up, it should attempt to `poll` the future
    /// again, which may or may not produce a final value.
    ///
    /// Note that on multiple calls to `poll`, only the [`Waker`] from the
    /// [`Context`] passed to the most recent call should be scheduled to
    /// receive a wakeup.
    ///
    /// # Runtime characteristics
    ///
    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
    /// progress, meaning that each time the current task is woken up, it should
    /// actively re-`poll` pending futures that it still has an interest in.
    ///
    /// The `poll` function is not called repeatedly in a tight loop -- instead,
    /// it should only be called when the future indicates that it is ready to
    /// make progress (by calling `wake()`). If you're familiar with the
    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
    /// typically do *not* suffer the same problems of "all wakeups must poll
    /// all events"; they are more like `epoll(4)`.
    ///
    /// An implementation of `poll` should strive to return quickly, and should
    /// not block. Returning quickly prevents unnecessarily clogging up
    /// threads or event loops. If it is known ahead of time that a call to
    /// `poll` may end up taking awhile, the work should be offloaded to a
    /// thread pool (or something similar) to ensure that `poll` can return
    /// quickly.
    ///
    /// # Panics
    ///
    /// Once a future has completed (returned `Ready` from `poll`), calling its
    /// `poll` method again may panic, block forever, or cause other kinds of
    /// problems; the `Future` trait places no requirements on the effects of
    /// such a call. However, as the `poll` method is not marked `unsafe`,
    /// Rust's usual rules apply: calls must never cause undefined behavior
    /// (memory corruption, incorrect use of `unsafe` functions, or the like),
    /// regardless of the future's state.
    ///
    /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending
    /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready
    /// [`Context`]: ../task/struct.Context.html
    /// [`Waker`]: ../task/struct.Waker.html
    /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake
    #[stable(feature = "futures_api", since = "1.36.0")]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl<F: ?Sized + Future + Unpin> Future for &mut F {
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        F::poll(Pin::new(&mut **self), cx)
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl
 Future for Pin

where
    P: Unpin + ops::DerefMut,
    P::Target: Future,
{
    type Output = <
::Target as Future>::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        Pin::get_mut(self).as_mut().poll(cx)
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove handler.rs<commit_after><|endoftext|>


<commit_before>// =================================================================
//
//                           * WARNING *
//
//                    This file is generated!
//
//  Changes made to this file will be overwritten. If changes are
//  required to the generated code, the service_crategen project
//  must be updated to generate the changes.
//
// =================================================================

#![doc(
    html_logo_url = "https://raw.githubusercontent.com/rusoto/rusoto/master/assets/logo-square.png"
)]
//!
Amazon Route 53

//!
//! If you're using the service, you're probably looking for [Route53Client](struct.Route53Client.html) and [Route53](trait.Route53.html).

extern crate futures;
extern crate rusoto_core;
extern crate xml;

mod custom;
mod generated;

pub use custom::*;
pub use generated::*;
<commit_msg>Let codegen fmt handle it.<commit_after>
// =================================================================
//
//                           * WARNING *
//
//                    This file is generated!
//
//  Changes made to this file will be overwritten. If changes are
//  required to the generated code, the service_crategen project
//  must be updated to generate the changes.
//
// =================================================================

#![doc(html_logo_url = "https://raw.githubusercontent.com/rusoto/rusoto/master/assets/logo-square.png")]
//!
Amazon Route 53

//!
//! If you're using the service, you're probably looking for [Route53Client](struct.Route53Client.html) and [Route53](trait.Route53.html).

extern crate futures;
extern crate rusoto_core;
extern crate xml;

mod generated;
mod custom;

pub use generated::*;
pub use custom::*;

<|endoftext|>


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

use driver::session;
use driver::session::Session;
use syntax::ast::{Crate, NodeId, item, item_fn};
use syntax::ast_map;
use syntax::attr;
use syntax::codemap::Span;
use syntax::parse::token::special_idents;
use syntax::visit;
use syntax::visit::Visitor;
use std::util;

struct EntryContext {
    session: Session,

    ast_map: ast_map::map,

    // The top-level function called 'main'
    main_fn: Option<(NodeId, Span)>,

    // The function that has attribute named 'main'
    attr_main_fn: Option<(NodeId, Span)>,

    // The function that has the attribute 'start' on it
    start_fn: Option<(NodeId, Span)>,

    // The functions that one might think are 'main' but aren't, e.g.
    // main functions not defined at the top level. For diagnostics.
    non_main_fns: ~[(NodeId, Span)],
}

struct EntryVisitor;

impl Visitor<@mut EntryContext> for EntryVisitor {
    fn visit_item(&mut self, item:@item, ctxt:@mut EntryContext) {
        find_item(item, ctxt, self);
    }
}

pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map) {

    // FIXME #4404 android JNI hacks
    if *session.building_library &&
        session.targ_cfg.os != session::OsAndroid {
        // No need to find a main function
        return;
    }

    // If the user wants no main function at all, then stop here.
    if attr::contains_name(crate.attrs, "no_main") {
        *session.entry_type = Some(session::EntryNone);
        return
    }

    let ctxt = @mut EntryContext {
        session: session,
        ast_map: ast_map,
        main_fn: None,
        attr_main_fn: None,
        start_fn: None,
        non_main_fns: ~[],
    };

    let mut v = EntryVisitor;

    visit::walk_crate(&mut v, crate, ctxt);

    configure_main(ctxt);
}

fn find_item(item: @item, ctxt: @mut EntryContext, visitor: &mut EntryVisitor) {
    match item.node {
        item_fn(*) => {
            if item.ident.name == special_idents::main.name {
                match ctxt.ast_map.find(&item.id) {
                    Some(&ast_map::node_item(_, path)) => {
                        if path.len() == 0 {
                            // This is a top-level function so can be 'main'
                            if ctxt.main_fn.is_none() {
                                ctxt.main_fn = Some((item.id, item.span));
                            } else {
                                ctxt.session.span_err(
                                    item.span,
                                    "multiple 'main' functions");
                            }
                        } else {
                            // This isn't main
                            ctxt.non_main_fns.push((item.id, item.span));
                        }
                    }
                    _ => util::unreachable()
                }
            }

            if attr::contains_name(item.attrs, "main") {
                if ctxt.attr_main_fn.is_none() {
                    ctxt.attr_main_fn = Some((item.id, item.span));
                } else {
                    ctxt.session.span_err(
                        item.span,
                        "multiple 'main' functions");
                }
            }

            if attr::contains_name(item.attrs, "start") {
                if ctxt.start_fn.is_none() {
                    ctxt.start_fn = Some((item.id, item.span));
                } else {
                    ctxt.session.span_err(
                        item.span,
                        "multiple 'start' functions");
                }
            }
        }
        _ => ()
    }

    visit::walk_item(visitor, item, ctxt);
}

fn configure_main(ctxt: @mut EntryContext) {
    let this = &mut *ctxt;
    if this.start_fn.is_some() {
        *this.session.entry_fn = this.start_fn;
        *this.session.entry_type = Some(session::EntryStart);
    } else if this.attr_main_fn.is_some() {
        *this.session.entry_fn = this.attr_main_fn;
        *this.session.entry_type = Some(session::EntryMain);
    } else if this.main_fn.is_some() {
        *this.session.entry_fn = this.main_fn;
        *this.session.entry_type = Some(session::EntryMain);
    } else {
        if !*this.session.building_library {
            // No main function
            this.session.err("main function not found");
            if !this.non_main_fns.is_empty() {
                // There were some functions named 'main' though. Try to give the user a hint.
                this.session.note("the main function must be defined at the crate level \
                                   but you have one or more functions named 'main' that are not \
                                   defined at the crate level. Either move the definition or \
                                   attach the `#[main]` attribute to override this behavior.");
                for &(_, span) in this.non_main_fns.iter() {
                    this.session.span_note(span, "here is a function named 'main'");
                }
            }
            this.session.abort_if_errors();
        } else {
            // If we *are* building a library, then we're on android where we still might
            // optionally want to translate main $4404
            assert_eq!(this.session.targ_cfg.os, session::OsAndroid);
        }
    }
}
<commit_msg>middle/entry.rs Visitor refactoring (#7081): unify Entry{Context,Visitor}.<commit_after>// Copyright 2012 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.

use driver::session;
use driver::session::Session;
use syntax::ast::{Crate, NodeId, item, item_fn};
use syntax::ast_map;
use syntax::attr;
use syntax::codemap::Span;
use syntax::parse::token::special_idents;
use syntax::visit;
use syntax::visit::Visitor;
use std::util;

struct EntryContext {
    session: Session,

    ast_map: ast_map::map,

    // The top-level function called 'main'
    main_fn: Option<(NodeId, Span)>,

    // The function that has attribute named 'main'
    attr_main_fn: Option<(NodeId, Span)>,

    // The function that has the attribute 'start' on it
    start_fn: Option<(NodeId, Span)>,

    // The functions that one might think are 'main' but aren't, e.g.
    // main functions not defined at the top level. For diagnostics.
    non_main_fns: ~[(NodeId, Span)],
}

impl Visitor<()> for EntryContext {
    fn visit_item(&mut self, item:@item, _:()) {
        find_item(item, self);
    }
}

pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map) {

    // FIXME #4404 android JNI hacks
    if *session.building_library &&
        session.targ_cfg.os != session::OsAndroid {
        // No need to find a main function
        return;
    }

    // If the user wants no main function at all, then stop here.
    if attr::contains_name(crate.attrs, "no_main") {
        *session.entry_type = Some(session::EntryNone);
        return
    }

    let mut ctxt = EntryContext {
        session: session,
        ast_map: ast_map,
        main_fn: None,
        attr_main_fn: None,
        start_fn: None,
        non_main_fns: ~[],
    };

    visit::walk_crate(&mut ctxt, crate, ());

    configure_main(&mut ctxt);
}

fn find_item(item: @item, ctxt: &mut EntryContext) {
    match item.node {
        item_fn(*) => {
            if item.ident.name == special_idents::main.name {
                match ctxt.ast_map.find(&item.id) {
                    Some(&ast_map::node_item(_, path)) => {
                        if path.len() == 0 {
                            // This is a top-level function so can be 'main'
                            if ctxt.main_fn.is_none() {
                                ctxt.main_fn = Some((item.id, item.span));
                            } else {
                                ctxt.session.span_err(
                                    item.span,
                                    "multiple 'main' functions");
                            }
                        } else {
                            // This isn't main
                            ctxt.non_main_fns.push((item.id, item.span));
                        }
                    }
                    _ => util::unreachable()
                }
            }

            if attr::contains_name(item.attrs, "main") {
                if ctxt.attr_main_fn.is_none() {
                    ctxt.attr_main_fn = Some((item.id, item.span));
                } else {
                    ctxt.session.span_err(
                        item.span,
                        "multiple 'main' functions");
                }
            }

            if attr::contains_name(item.attrs, "start") {
                if ctxt.start_fn.is_none() {
                    ctxt.start_fn = Some((item.id, item.span));
                } else {
                    ctxt.session.span_err(
                        item.span,
                        "multiple 'start' functions");
                }
            }
        }
        _ => ()
    }

    visit::walk_item(ctxt, item, ());
}

fn configure_main(this: &mut EntryContext) {
    if this.start_fn.is_some() {
        *this.session.entry_fn = this.start_fn;
        *this.session.entry_type = Some(session::EntryStart);
    } else if this.attr_main_fn.is_some() {
        *this.session.entry_fn = this.attr_main_fn;
        *this.session.entry_type = Some(session::EntryMain);
    } else if this.main_fn.is_some() {
        *this.session.entry_fn = this.main_fn;
        *this.session.entry_type = Some(session::EntryMain);
    } else {
        if !*this.session.building_library {
            // No main function
            this.session.err("main function not found");
            if !this.non_main_fns.is_empty() {
                // There were some functions named 'main' though. Try to give the user a hint.
                this.session.note("the main function must be defined at the crate level \
                                   but you have one or more functions named 'main' that are not \
                                   defined at the crate level. Either move the definition or \
                                   attach the `#[main]` attribute to override this behavior.");
                for &(_, span) in this.non_main_fns.iter() {
                    this.session.span_note(span, "here is a function named 'main'");
                }
            }
            this.session.abort_if_errors();
        } else {
            // If we *are* building a library, then we're on android where we still might
            // optionally want to translate main $4404
            assert_eq!(this.session.targ_cfg.os, session::OsAndroid);
        }
    }
}
<|endoftext|>


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

//! Implementation of running at_exit routines
//!
//! Documentation can be found on the `rt::at_exit` function.

use core::prelude::*;

use alloc::owned::Box;
use collections::vec::Vec;
use core::atomics;
use core::mem;

use exclusive::Exclusive;

type Queue = Exclusive<Vec<proc():Send>>;

static mut QUEUE: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
static mut RUNNING: atomics::AtomicBool = atomics::INIT_ATOMIC_BOOL;

pub fn init() {
    let state: Box<Queue> = box Exclusive::new(Vec::new());
    unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        rtassert!(QUEUE.swap(mem::transmute(state), atomics::SeqCst) == 0);
    }
}

pub fn push(f: proc():Send) {
    unsafe {
        // Note that the check against 0 for the queue pointer is not atomic at
        // all with respect to `run`, meaning that this could theoretically be a
        // use-after-free. There's not much we can do to protect against that,
        // however. Let's just assume a well-behaved runtime and go from there!
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.load(atomics::SeqCst);
        rtassert!(queue != 0);
        (*(queue as *Queue)).lock().push(f);
    }
}

pub fn run() {
    let cur = unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.swap(0, atomics::SeqCst);
        rtassert!(queue != 0);

        let queue: Box<Queue> = mem::transmute(queue);
        mem::replace(&mut *queue.lock(), Vec::new())
    };

    for to_run in cur.move_iter() {
        to_run();
    }
}
<commit_msg>rustrt: Fix invalid reads caught by valgrind<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of running at_exit routines
//!
//! Documentation can be found on the `rt::at_exit` function.

use core::prelude::*;

use alloc::owned::Box;
use collections::vec::Vec;
use core::atomics;
use core::mem;

use exclusive::Exclusive;

type Queue = Exclusive<Vec<proc():Send>>;

static mut QUEUE: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
static mut RUNNING: atomics::AtomicBool = atomics::INIT_ATOMIC_BOOL;

pub fn init() {
    let state: Box<Queue> = box Exclusive::new(Vec::new());
    unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        rtassert!(QUEUE.swap(mem::transmute(state), atomics::SeqCst) == 0);
    }
}

pub fn push(f: proc():Send) {
    unsafe {
        // Note that the check against 0 for the queue pointer is not atomic at
        // all with respect to `run`, meaning that this could theoretically be a
        // use-after-free. There's not much we can do to protect against that,
        // however. Let's just assume a well-behaved runtime and go from there!
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.load(atomics::SeqCst);
        rtassert!(queue != 0);
        (*(queue as *Queue)).lock().push(f);
    }
}

pub fn run() {
    let cur = unsafe {
        rtassert!(!RUNNING.load(atomics::SeqCst));
        let queue = QUEUE.swap(0, atomics::SeqCst);
        rtassert!(queue != 0);

        let queue: Box<Queue> = mem::transmute(queue);
        let v = mem::replace(&mut *queue.lock(), Vec::new());
        v
    };

    for to_run in cur.move_iter() {
        to_run();
    }
}
<|endoftext|>


<commit_before>use crate::types::SqlType;
use crate::ColumnName;
use crate::FromDao;
use crate::TableName;
use uuid::Uuid;

#[derive(Debug, PartialEq, Clone)]
pub struct Column {
    pub table: TableName,
    pub name: ColumnName,
    pub comment: Option<String>,
    pub specification: ColumnSpecification,
    pub stat: Option<ColumnStat>,
}

impl Column {
    /// check all the column constraint if any has AutoIncrement
    pub fn is_autoincrement(&self) -> bool {
        self.specification
            .constraints
            .iter()
            .any(|c| *c == ColumnConstraint::AutoIncrement)
    }

    /// check if any of the column constraint default is generated from uuid
    pub fn default_is_generated_uuid(&self) -> bool {
        self.specification.constraints.iter().any(|c| match *c {
            ColumnConstraint::DefaultValue(ref literal) => match *literal {
                Literal::UuidGenerateV4 => true,
                _ => false,
            },
            _ => false,
        })
    }

    pub fn is_not_null(&self) -> bool {
        self.specification.constraints.iter().any(|c| match *c {
            ColumnConstraint::NotNull => true,
            _ => false,
        })
    }

    pub fn get_sql_type(&self) -> SqlType {
        self.specification.sql_type.clone()
    }

    pub fn cast_as(&self) -> Option<SqlType> {
        self.get_sql_type().cast_as()
    }

    pub fn has_generated_default(&self) -> bool {
        self.specification.constraints.iter().any(|c| match *c {
            ColumnConstraint::DefaultValue(ref literal) => match *literal {
                Literal::Bool(_) => true,
                Literal::Null => false,
                Literal::Integer(_) => true,
                Literal::Double(_) => true,
                Literal::UuidGenerateV4 => true,
                Literal::Uuid(_) => true,
                Literal::String(_) => false,
                Literal::Blob(_) => false,
                Literal::CurrentTime => true,
                Literal::CurrentDate => true,
                Literal::CurrentTimestamp => true,
                Literal::ArrayInt(_) => false,
                Literal::ArrayFloat(_) => false,
                Literal::ArrayString(_) => false,
            },
            _ => false,
        })
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct ColumnSpecification {
    pub sql_type: SqlType,
    pub capacity: Option<Capacity>,
    pub constraints: Vec<ColumnConstraint>,
}

impl ColumnSpecification {
    pub fn get_limit(&self) -> Option<i32> {
        match self.capacity {
            Some(ref capacity) => capacity.get_limit(),
            None => None,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum Capacity {
    Limit(i32),
    Range(i32, i32),
}

impl Capacity {
    fn get_limit(&self) -> Option<i32> {
        match *self {
            Capacity::Limit(limit) => Some(limit),
            Capacity::Range(_whole, _decimal) => None,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum ColumnConstraint {
    NotNull,
    DefaultValue(Literal),
    AutoIncrement,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Literal {
    Bool(bool),
    Null,
    Integer(i64),
    Double(f64),
    UuidGenerateV4, // pg: uuid_generate_v4();
    Uuid(Uuid),
    String(String),
    Blob(Vec<u8>),
    CurrentTime,      // pg: now()
    CurrentDate,      //pg: today()
    CurrentTimestamp, // pg: now()
    ArrayInt(Vec<i64>),
    ArrayFloat(Vec<f64>),
    ArrayString(Vec<String>),
}

/// column stat, derive from pg_stats
#[derive(Debug, PartialEq, FromDao, Clone)]
pub struct ColumnStat {
    pub avg_width: i32, //average width of the column, (the number of characters)
    //most_common_values: Value,//top 5 most common values
    pub n_distinct: f32, // the number of distinct values of these column
}

impl From<i64> for Literal {
    fn from(i: i64) -> Self {
        Literal::Integer(i)
    }
}

impl From<String> for Literal {
    fn from(s: String) -> Self {
        Literal::String(s)
    }
}

impl<'a> From<&'a str> for Literal {
    fn from(s: &'a str) -> Self {
        Literal::String(String::from(s))
    }
}
<commit_msg>Using the derived from dao<commit_after>use crate::types::SqlType;
use crate::ColumnName;
use rustorm_codegen::FromDao;
use crate::TableName;
use uuid::Uuid;

#[derive(Debug, PartialEq, Clone)]
pub struct Column {
    pub table: TableName,
    pub name: ColumnName,
    pub comment: Option<String>,
    pub specification: ColumnSpecification,
    pub stat: Option<ColumnStat>,
}

impl Column {
    /// check all the column constraint if any has AutoIncrement
    pub fn is_autoincrement(&self) -> bool {
        self.specification
            .constraints
            .iter()
            .any(|c| *c == ColumnConstraint::AutoIncrement)
    }

    /// check if any of the column constraint default is generated from uuid
    pub fn default_is_generated_uuid(&self) -> bool {
        self.specification.constraints.iter().any(|c| match *c {
            ColumnConstraint::DefaultValue(ref literal) => match *literal {
                Literal::UuidGenerateV4 => true,
                _ => false,
            },
            _ => false,
        })
    }

    pub fn is_not_null(&self) -> bool {
        self.specification.constraints.iter().any(|c| match *c {
            ColumnConstraint::NotNull => true,
            _ => false,
        })
    }

    pub fn get_sql_type(&self) -> SqlType {
        self.specification.sql_type.clone()
    }

    pub fn cast_as(&self) -> Option<SqlType> {
        self.get_sql_type().cast_as()
    }

    pub fn has_generated_default(&self) -> bool {
        self.specification.constraints.iter().any(|c| match *c {
            ColumnConstraint::DefaultValue(ref literal) => match *literal {
                Literal::Bool(_) => true,
                Literal::Null => false,
                Literal::Integer(_) => true,
                Literal::Double(_) => true,
                Literal::UuidGenerateV4 => true,
                Literal::Uuid(_) => true,
                Literal::String(_) => false,
                Literal::Blob(_) => false,
                Literal::CurrentTime => true,
                Literal::CurrentDate => true,
                Literal::CurrentTimestamp => true,
                Literal::ArrayInt(_) => false,
                Literal::ArrayFloat(_) => false,
                Literal::ArrayString(_) => false,
            },
            _ => false,
        })
    }
}

#[derive(Debug, PartialEq, Clone)]
pub struct ColumnSpecification {
    pub sql_type: SqlType,
    pub capacity: Option<Capacity>,
    pub constraints: Vec<ColumnConstraint>,
}

impl ColumnSpecification {
    pub fn get_limit(&self) -> Option<i32> {
        match self.capacity {
            Some(ref capacity) => capacity.get_limit(),
            None => None,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum Capacity {
    Limit(i32),
    Range(i32, i32),
}

impl Capacity {
    fn get_limit(&self) -> Option<i32> {
        match *self {
            Capacity::Limit(limit) => Some(limit),
            Capacity::Range(_whole, _decimal) => None,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum ColumnConstraint {
    NotNull,
    DefaultValue(Literal),
    AutoIncrement,
}

#[derive(Debug, PartialEq, Clone)]
pub enum Literal {
    Bool(bool),
    Null,
    Integer(i64),
    Double(f64),
    UuidGenerateV4, // pg: uuid_generate_v4();
    Uuid(Uuid),
    String(String),
    Blob(Vec<u8>),
    CurrentTime,      // pg: now()
    CurrentDate,      //pg: today()
    CurrentTimestamp, // pg: now()
    ArrayInt(Vec<i64>),
    ArrayFloat(Vec<f64>),
    ArrayString(Vec<String>),
}

/// column stat, derive from pg_stats
#[derive(Debug, PartialEq, FromDao, Clone)]
pub struct ColumnStat {
    pub avg_width: i32, //average width of the column, (the number of characters)
    //most_common_values: Value,//top 5 most common values
    pub n_distinct: f32, // the number of distinct values of these column
}

impl From<i64> for Literal {
    fn from(i: i64) -> Self {
        Literal::Integer(i)
    }
}

impl From<String> for Literal {
    fn from(s: String) -> Self {
        Literal::String(s)
    }
}

impl<'a> From<&'a str> for Literal {
    fn from(s: &'a str) -> Self {
        Literal::String(String::from(s))
    }
}
<|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.

extern crate toml;

use {NewlineStyle, BraceStyle, ReturnIndent, StructLitStyle};
use lists::{SeparatorTactic, ListTactic};
use issues::ReportTactic;

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum BlockIndentStyle {
    // Same level as parent.
    Inherit,
    // One level deeper than parent.
    Tabbed,
    // Aligned with block open.
    Visual,
}

impl_enum_decodable!(BlockIndentStyle, Inherit, Tabbed, Visual);

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Density {
    // Fit as much on one line as possible.
    Compressed,
    // Use more lines.
    Tall,
}

impl_enum_decodable!(Density, Compressed, Tall);

impl Density {
    pub fn to_list_tactic(self) -> ListTactic {
        match self {
            Density::Compressed => ListTactic::Mixed,
            Density::Tall => ListTactic::HorizontalVertical,
        }
    }
}

macro_rules! create_config {
    ($($i:ident: $ty:ty),+ $(,)*) => (
        #[derive(RustcDecodable, Clone)]
        pub struct Config {
            $(pub $i: $ty),+
        }

        impl Config {
            pub fn from_toml(toml: &str) -> Config {
                let parsed = toml.parse().unwrap();
                match toml::decode(parsed) {
                    Some(decoded) => decoded,
                    None => {
                        println!("Decoding config file failed. Config:\n{}", toml);
                        let parsed: toml::Value = toml.parse().unwrap();
                        println!("\n\nParsed:\n{:?}", parsed);
                        panic!();
                    }
                }
            }

            pub fn override_value(&mut self, key: &str, val: &str) {
                match key {
                    $(
                        stringify!($i) => {
                            self.$i = val.parse::<$ty>().unwrap();
                        }
                    )+
                    _ => panic!("Bad config key!")
                }
            }
        }
    )
}

create_config! {
    max_width: usize,
    ideal_width: usize,
    leeway: usize,
    tab_spaces: usize,
    newline_style: NewlineStyle,
    fn_brace_style: BraceStyle,
    fn_return_indent: ReturnIndent,
    fn_args_paren_newline: bool,
    fn_args_density: Density,
    fn_args_layout: StructLitStyle,
    fn_arg_indent: BlockIndentStyle,
    where_density: Density, // Should we at least try to put the where clause on the same line as
                            // the rest of the function decl?
    where_indent: BlockIndentStyle, // Visual will be treated like Tabbed
    where_layout: ListTactic,
    where_pred_indent: BlockIndentStyle,
    generics_indent: BlockIndentStyle,
    struct_trailing_comma: SeparatorTactic,
    struct_lit_trailing_comma: SeparatorTactic,
    struct_lit_style: StructLitStyle,
    enum_trailing_comma: bool,
    report_todo: ReportTactic,
    report_fixme: ReportTactic,
    reorder_imports: bool, // Alphabetically, case sensitive.
    expr_indent_style: BlockIndentStyle,
    closure_indent_style: BlockIndentStyle,
    single_line_if_else: bool,
    format_strings: bool,
}

impl Default for Config {

    fn default() -> Config {
        Config {
            max_width: 100,
            ideal_width: 80,
            leeway: 5,
            tab_spaces: 4,
            newline_style: NewlineStyle::Unix,
            fn_brace_style: BraceStyle::SameLineWhere,
            fn_return_indent: ReturnIndent::WithArgs,
            fn_args_paren_newline: true,
            fn_args_density: Density::Tall,
            fn_args_layout: StructLitStyle::Visual,
            fn_arg_indent: BlockIndentStyle::Visual,
            where_density: Density::Tall,
            where_indent: BlockIndentStyle::Tabbed,
            where_layout: ListTactic::Vertical,
            where_pred_indent: BlockIndentStyle::Visual,
            generics_indent: BlockIndentStyle::Visual,
            struct_trailing_comma: SeparatorTactic::Vertical,
            struct_lit_trailing_comma: SeparatorTactic::Vertical,
            struct_lit_style: StructLitStyle::Block,
            enum_trailing_comma: true,
            report_todo: ReportTactic::Always,
            report_fixme: ReportTactic::Never,
            reorder_imports: false,
            expr_indent_style: BlockIndentStyle::Tabbed,
            closure_indent_style: BlockIndentStyle::Visual,
            single_line_if_else: false,
            format_strings: true,
        }
    }

}
<commit_msg>Allow partial rustfmt.toml<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.

extern crate toml;

use {NewlineStyle, BraceStyle, ReturnIndent, StructLitStyle};
use lists::{SeparatorTactic, ListTactic};
use issues::ReportTactic;

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum BlockIndentStyle {
    // Same level as parent.
    Inherit,
    // One level deeper than parent.
    Tabbed,
    // Aligned with block open.
    Visual,
}

impl_enum_decodable!(BlockIndentStyle, Inherit, Tabbed, Visual);

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Density {
    // Fit as much on one line as possible.
    Compressed,
    // Use more lines.
    Tall,
}

impl_enum_decodable!(Density, Compressed, Tall);

impl Density {
    pub fn to_list_tactic(self) -> ListTactic {
        match self {
            Density::Compressed => ListTactic::Mixed,
            Density::Tall => ListTactic::HorizontalVertical,
        }
    }
}

macro_rules! create_config {
    ($($i:ident: $ty:ty),+ $(,)*) => (
        #[derive(RustcDecodable, Clone)]
        pub struct Config {
            $(pub $i: $ty),+
        }

        // Just like the Config struct but with each property wrapped
        // as Option<T>. This is used to parse a rustfmt.toml that doesn't
        // specity all properties of `Config`.
        // We first parse into `ParsedConfig`, then create a default `Config`
        // and overwrite the properties with corresponding values from `ParsedConfig`
        #[derive(RustcDecodable, Clone)]
        pub struct ParsedConfig {
            $(pub $i: Option<$ty>),+
        }

        impl Config {

            fn fill_from_parsed_config(mut self, parsed: &ParsedConfig) -> Config {
            $(
                if let Some(val) = parsed.$i {
                    self.$i = val;
                }
            )+
                self
            }

            pub fn from_toml(toml: &str) -> Config {
                let parsed = toml.parse().unwrap();
                let parsed_config:ParsedConfig = match toml::decode(parsed) {
                    Some(decoded) => decoded,
                    None => {
                        println!("Decoding config file failed. Config:\n{}", toml);
                        let parsed: toml::Value = toml.parse().unwrap();
                        println!("\n\nParsed:\n{:?}", parsed);
                        panic!();
                    }
                };
                Config::default().fill_from_parsed_config(&parsed_config)
            }

            pub fn override_value(&mut self, key: &str, val: &str) {
                match key {
                    $(
                        stringify!($i) => {
                            self.$i = val.parse::<$ty>().unwrap();
                        }
                    )+
                    _ => panic!("Bad config key!")
                }
            }
        }
    )
}

create_config! {
    max_width: usize,
    ideal_width: usize,
    leeway: usize,
    tab_spaces: usize,
    newline_style: NewlineStyle,
    fn_brace_style: BraceStyle,
    fn_return_indent: ReturnIndent,
    fn_args_paren_newline: bool,
    fn_args_density: Density,
    fn_args_layout: StructLitStyle,
    fn_arg_indent: BlockIndentStyle,
    where_density: Density, // Should we at least try to put the where clause on the same line as
                            // the rest of the function decl?
    where_indent: BlockIndentStyle, // Visual will be treated like Tabbed
    where_layout: ListTactic,
    where_pred_indent: BlockIndentStyle,
    generics_indent: BlockIndentStyle,
    struct_trailing_comma: SeparatorTactic,
    struct_lit_trailing_comma: SeparatorTactic,
    struct_lit_style: StructLitStyle,
    enum_trailing_comma: bool,
    report_todo: ReportTactic,
    report_fixme: ReportTactic,
    reorder_imports: bool, // Alphabetically, case sensitive.
    expr_indent_style: BlockIndentStyle,
    closure_indent_style: BlockIndentStyle,
    single_line_if_else: bool,
    format_strings: bool,
}

impl Default for Config {

    fn default() -> Config {
        Config {
            max_width: 100,
            ideal_width: 80,
            leeway: 5,
            tab_spaces: 4,
            newline_style: NewlineStyle::Unix,
            fn_brace_style: BraceStyle::SameLineWhere,
            fn_return_indent: ReturnIndent::WithArgs,
            fn_args_paren_newline: true,
            fn_args_density: Density::Tall,
            fn_args_layout: StructLitStyle::Visual,
            fn_arg_indent: BlockIndentStyle::Visual,
            where_density: Density::Tall,
            where_indent: BlockIndentStyle::Tabbed,
            where_layout: ListTactic::Vertical,
            where_pred_indent: BlockIndentStyle::Visual,
            generics_indent: BlockIndentStyle::Visual,
            struct_trailing_comma: SeparatorTactic::Vertical,
            struct_lit_trailing_comma: SeparatorTactic::Vertical,
            struct_lit_style: StructLitStyle::Block,
            enum_trailing_comma: true,
            report_todo: ReportTactic::Always,
            report_fixme: ReportTactic::Never,
            reorder_imports: false,
            expr_indent_style: BlockIndentStyle::Tabbed,
            closure_indent_style: BlockIndentStyle::Visual,
            single_line_if_else: false,
            format_strings: true,
        }
    }

}
<|endoftext|>


<commit_before>//! Error types used in the gerber-types library.

use std::io::Error as IoError;

quick_error! {
    #[derive(Debug, Clone)]
    pub enum GerberError {
        /// Conversion between two types failed
        ConversionError(msg: String) {}
        /// Bad coordinate format
        CoordinateFormatError(msg: String) {}
        /// A value is out of range
        RangeError(msg: String) {}
        /// Required data is missing
        MissingDataError(msg: String) {}
        /// I/O error during code generation
        IoError(err: IoError) {
            cause(err)
            from()
        }
    }
}

pub type GerberResult<T> = Result<T, GerberError>;
<commit_msg>Remove Clone from GerberError<commit_after>//! Error types used in the gerber-types library.

use std::io::Error as IoError;

quick_error! {
    #[derive(Debug)]
    pub enum GerberError {
        /// Conversion between two types failed
        ConversionError(msg: String) {}
        /// Bad coordinate format
        CoordinateFormatError(msg: String) {}
        /// A value is out of range
        RangeError(msg: String) {}
        /// Required data is missing
        MissingDataError(msg: String) {}
        /// I/O error during code generation
        IoError(err: IoError) {
            cause(err)
            from()
        }
    }
}

pub type GerberResult<T> = Result<T, GerberError>;
<|endoftext|>