<commit_before>//! Types which represent a native SQL data type, and the conversions between
//! them and Rust primitives. The structs in this module are *only* used as
//! markers to represent a SQL type, and shouldn't be used in your structs. See
//! the documentation for each type to see the Rust types that can be used with
//! a corresponding SQL type. Additional types can be added by other crates.
//!
//! To see which Rust types can be used with a given SQL type, see the
//! "Implementors" section of the [`ToSql`][ToSql] and [`FromSql`][FromSql]
//! traits, or see the documentation for that SQL type.
//!
//! [ToSql]: /diesel/types/trait.ToSql.html
//! [FromSql]: /diesel/types/trait.FromSql.html
//!
//! Any backend specific types are re-exported through this module
pub mod ops;
mod ord;
#[macro_use]
#[doc(hidden)]
pub mod impls;
mod fold;

use std::fmt;

#[doc(hidden)]
pub mod structs {
    pub mod data_types {
        //! Structs to represent the primitive equivalent of SQL types where
        //! there is no existing Rust primitive, or where using it would be
        //! confusing (such as date and time types). This module will re-export
        //! all backend specific data structures when compiled against that
        //! backend.
        #[cfg(feature = "postgres")]
        pub use pg::data_types::*;
    }
}

/// Marker trait for types which can be compared for ordering.
pub use self::ord::SqlOrd;

/// Marker trait for types which can be folded for a sum.
pub use self::fold::Foldable;

use backend::{Backend, TypeMetadata};
use row::Row;
use std::error::Error;
use std::io::Write;

/// The boolean SQL type. On SQLite this is emulated with an integer.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`bool`][bool]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`bool`][bool]
///
/// [bool]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
#[derive(Debug, Clone, Copy, Default)] pub struct Bool;

/// The small integer SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`i16`][i16]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`i16`][i16]
///
/// [i16]: https://doc.rust-lang.org/nightly/std/primitive.i16.html
#[derive(Debug, Clone, Copy, Default)] pub struct SmallInt;
#[doc(hidden)] pub type Int2 = SmallInt;
#[doc(hidden)] pub type Smallint = SmallInt;

/// The integer SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`i32`][i32]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`i32`][i32]
///
/// [i32]: https://doc.rust-lang.org/nightly/std/primitive.i32.html
#[derive(Debug, Clone, Copy, Default)] pub struct Integer;
#[doc(hidden)] pub type Int4 = Integer;

/// The big integer SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`i64`][i64]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`i64`][i64]
///
/// [i64]: https://doc.rust-lang.org/nightly/std/primitive.i64.html
#[derive(Debug, Clone, Copy, Default)] pub struct BigInt;
#[doc(hidden)] pub type Int8 = BigInt;
#[doc(hidden)] pub type Bigint = BigInt;

/// The float SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`f32`][f32]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`f32`][f32]
///
/// [f32]: https://doc.rust-lang.org/nightly/std/primitive.f32.html
#[derive(Debug, Clone, Copy, Default)] pub struct Float;
#[doc(hidden)] pub type Float4 = Float;

/// The double precision float SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`f64`][f64]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`f64`][f64]
///
/// [f64]: https://doc.rust-lang.org/nightly/std/primitive.f64.html
#[derive(Debug, Clone, Copy, Default)] pub struct Double;
#[doc(hidden)] pub type Float8 = Double;

/// The numeric SQL type.
///
/// This type does not currently have any corresponding Rust types. On SQLite,
/// [`Double`](struct.Double.html) should be used instead.
#[derive(Debug, Clone, Copy, Default)] pub struct Numeric;

#[cfg(not(feature="postgres"))]
impl NotNull for Numeric {}

/// The text SQL type.
///
/// On all backends strings must be valid UTF-8.
/// On PostgreSQL strings must not include nul bytes.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`String`][String]
/// - [`&str`][str]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`String`][String]
///
/// [String]: https://doc.rust-lang.org/nightly/std/string/struct.String.html
/// [str]: https://doc.rust-lang.org/nightly/std/primitive.str.html
#[derive(Debug, Clone, Copy, Default)] pub struct Text;
pub type VarChar = Text;
#[doc(hidden)] pub type Varchar = VarChar;

/// The binary SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`Vec<u8>`][Vec]
/// - [`&[u8]`][slice]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`Vec<u8>`][Vec]
///
/// [Vec]: https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html
/// [slice]: https://doc.rust-lang.org/nightly/std/primitive.slice.html
#[derive(Debug, Clone, Copy, Default)] pub struct Binary;

/// The date SQL type.
///
/// This type is currently only implemented for PostgreSQL and SQLite.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`chrono::NaiveDate`][NaiveDate] with `feature = "chrono"`
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`chrono::NaiveDate`][NaiveDate] with `feature = "chrono"`
///
/// [NaiveDate]: /chrono/naive/date/struct.NaiveDate.html
#[derive(Debug, Clone, Copy, Default)] pub struct Date;

/// The interval SQL type.
///
/// This type is currently only implemented for PostgreSQL.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`PgInterval`][PgInterval] which can be constructed using the [interval
///   DSLs][interval dsls]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`PgInterval`][PgInterval] which can be constructed using the [interval
///   DSLs][interval dsls]
///
/// [PgInterval]: /diesel/pg/data_types/struct.PgInterval.html
/// [interval dsls]: /diesel/pg/expression/extensions/index.html
#[derive(Debug, Clone, Copy, Default)] pub struct Interval;

/// The time SQL type.
///
/// This type is currently only implemented for PostgreSQL and SQLite.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`chrono::NaiveTime`][NaiveTime] with `feature = "chrono"`
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`chrono::NaiveTime`][NaiveTime] with `feature = "chrono"`
///
/// [NaiveTime]: /chrono/naive/time/struct.NaiveTime.html
#[derive(Debug, Clone, Copy, Default)] pub struct Time;

/// The timestamp/datetime SQL type.
///
/// This type is currently only implemented for PostgreSQL and SQLite.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`std::time::SystemTime`][SystemTime] (PG only)
/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
/// - [`time::Timespec`][Timespec] with `feature = "deprecated-time"` (PG only)
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`std::time::SystemTime`][SystemTime] (PG only)
/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
/// - [`time::Timespec`][Timespec] with `feature = "deprecated-time"` (PG only)
///
/// [SystemTime]: https://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html
/// [NaiveDateTime]: /chrono/naive/datetime/struct.NaiveDateTime.html
/// [Timespec]: /time/struct.Timespec.html
#[derive(Debug, Clone, Copy, Default)] pub struct Timestamp;

/// The nullable SQL type. This wraps another SQL type to indicate that it can
/// be null. By default all values are assumed to be `NOT NULL`.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - Any `T` which implements `ToSql<ST>`
/// - `Option<T>` for any `T` which implements `ToSql<ST>`
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - `Option<T>` for any `T` which implements `FromSql<ST>`
#[derive(Debug, Clone, Copy, Default)] pub struct Nullable<ST: NotNull>(ST);

#[cfg(feature = "postgres")]
pub use pg::types::sql_types::*;

pub trait HasSqlType<ST>: TypeMetadata {
    fn metadata() -> Self::TypeMetadata;

    fn row_metadata(out: &mut Vec<Self::TypeMetadata>) {
        out.push(Self::metadata())
    }
}

pub trait NotNull {
}

pub trait IntoNullable {
    type Nullable;
}

impl<T: NotNull> IntoNullable for T {
    type Nullable = Nullable<T>;
}

impl<T: NotNull> IntoNullable for Nullable<T> {
    type Nullable = Nullable<T>;
}

/// How to deserialize a single field of a given type. The input will always be
/// the binary representation, not the text.
pub trait FromSql<A, DB: Backend + HasSqlType<A>>: Sized {
    fn from_sql(bytes: Option<&DB::RawValue>) -> Result<Self, Box<Error+Send+Sync>>;
}

/// How to deserialize multiple fields, with a known type. This type is
/// implemented for tuples of various sizes.
pub trait FromSqlRow<A, DB: Backend + HasSqlType<A>>: Sized {
    fn build_from_row<T: Row<DB>>(row: &mut T) -> Result<Self, Box<Error+Send+Sync>>;

    /// The number of fields that this type will consume. Should be equal to
    /// the number of times you would call `row.take()` in `build_from_row`
    fn fields_needed() -> usize {
        1
    }
}

#[cfg(feature = "unstable")]
impl<T, ST, DB> FromSqlRow<Nullable<ST>, DB> for Option<T> where
    T: FromSqlRow<ST, DB>,
    DB: Backend + HasSqlType<ST>,
    ST: NotNull,
{
    default fn build_from_row<R: Row<DB>>(row: &mut R) -> Result<Self, Box<Error+Send+Sync>> {
        if row.next_is_null(1) {
            row.take();
            Ok(None)
        } else {
            T::build_from_row(row).map(Some)
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    Yes,
    No,
}

/// Serializes a single value to be sent to the database. The output will be
/// included as a bind parameter, and is expected to be the binary format, not
/// text.
pub trait ToSql<A, DB: Backend + HasSqlType<A>>: fmt::Debug {
    fn to_sql<W: Write>(&self, out: &mut W) -> Result<IsNull, Box<Error+Send+Sync>>;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T where
    DB: Backend + HasSqlType<A>,
    T: ToSql<A, DB>,
{
    fn to_sql<W: Write>(&self, out: &mut W) -> Result<IsNull, Box<Error+Send+Sync>> {
        (*self).to_sql(out)
    }
}
<commit_msg>Add docs for Numeric type<commit_after>//! Types which represent a native SQL data type, and the conversions between
//! them and Rust primitives. The structs in this module are *only* used as
//! markers to represent a SQL type, and shouldn't be used in your structs. See
//! the documentation for each type to see the Rust types that can be used with
//! a corresponding SQL type. Additional types can be added by other crates.
//!
//! To see which Rust types can be used with a given SQL type, see the
//! "Implementors" section of the [`ToSql`][ToSql] and [`FromSql`][FromSql]
//! traits, or see the documentation for that SQL type.
//!
//! [ToSql]: /diesel/types/trait.ToSql.html
//! [FromSql]: /diesel/types/trait.FromSql.html
//!
//! Any backend specific types are re-exported through this module
pub mod ops;
mod ord;
#[macro_use]
#[doc(hidden)]
pub mod impls;
mod fold;

use std::fmt;

#[doc(hidden)]
pub mod structs {
    pub mod data_types {
        //! Structs to represent the primitive equivalent of SQL types where
        //! there is no existing Rust primitive, or where using it would be
        //! confusing (such as date and time types). This module will re-export
        //! all backend specific data structures when compiled against that
        //! backend.
        #[cfg(feature = "postgres")]
        pub use pg::data_types::*;
    }
}

/// Marker trait for types which can be compared for ordering.
pub use self::ord::SqlOrd;

/// Marker trait for types which can be folded for a sum.
pub use self::fold::Foldable;

use backend::{Backend, TypeMetadata};
use row::Row;
use std::error::Error;
use std::io::Write;

/// The boolean SQL type. On SQLite this is emulated with an integer.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`bool`][bool]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`bool`][bool]
///
/// [bool]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
#[derive(Debug, Clone, Copy, Default)] pub struct Bool;

/// The small integer SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`i16`][i16]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`i16`][i16]
///
/// [i16]: https://doc.rust-lang.org/nightly/std/primitive.i16.html
#[derive(Debug, Clone, Copy, Default)] pub struct SmallInt;
#[doc(hidden)] pub type Int2 = SmallInt;
#[doc(hidden)] pub type Smallint = SmallInt;

/// The integer SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`i32`][i32]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`i32`][i32]
///
/// [i32]: https://doc.rust-lang.org/nightly/std/primitive.i32.html
#[derive(Debug, Clone, Copy, Default)] pub struct Integer;
#[doc(hidden)] pub type Int4 = Integer;

/// The big integer SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`i64`][i64]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`i64`][i64]
///
/// [i64]: https://doc.rust-lang.org/nightly/std/primitive.i64.html
#[derive(Debug, Clone, Copy, Default)] pub struct BigInt;
#[doc(hidden)] pub type Int8 = BigInt;
#[doc(hidden)] pub type Bigint = BigInt;

/// The float SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`f32`][f32]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`f32`][f32]
///
/// [f32]: https://doc.rust-lang.org/nightly/std/primitive.f32.html
#[derive(Debug, Clone, Copy, Default)] pub struct Float;
#[doc(hidden)] pub type Float4 = Float;

/// The double precision float SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`f64`][f64]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`f64`][f64]
///
/// [f64]: https://doc.rust-lang.org/nightly/std/primitive.f64.html
#[derive(Debug, Clone, Copy, Default)] pub struct Double;
#[doc(hidden)] pub type Float8 = Double;

/// The numeric SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`bigdecimal::BigDecimal`][bigdecimal] (currenty PostgreSQL only, requires the `numeric`
/// feature, which depends on the
/// [`bigdecimal`][bigdecimal] crate)
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`bigdecimal::BigDecimal`][BigDecimal] (currenty PostgreSQL only, requires the `numeric`
/// feature, which depends on the
/// [`bigdecimal`][bigdecimal] crate)
///
/// On SQLite, [`Double`](struct.Double.html) should be used instead.
///
/// [BigDecimal]: /bigdecimal/struct.BigDecimal.html
/// [bigdecimal]: /bigdecimal/index.html
#[derive(Debug, Clone, Copy, Default)] pub struct Numeric;

#[cfg(not(feature="postgres"))]
impl NotNull for Numeric {}

/// The text SQL type.
///
/// On all backends strings must be valid UTF-8.
/// On PostgreSQL strings must not include nul bytes.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`String`][String]
/// - [`&str`][str]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`String`][String]
///
/// [String]: https://doc.rust-lang.org/nightly/std/string/struct.String.html
/// [str]: https://doc.rust-lang.org/nightly/std/primitive.str.html
#[derive(Debug, Clone, Copy, Default)] pub struct Text;
pub type VarChar = Text;
#[doc(hidden)] pub type Varchar = VarChar;

/// The binary SQL type.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`Vec<u8>`][Vec]
/// - [`&[u8]`][slice]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`Vec<u8>`][Vec]
///
/// [Vec]: https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html
/// [slice]: https://doc.rust-lang.org/nightly/std/primitive.slice.html
#[derive(Debug, Clone, Copy, Default)] pub struct Binary;

/// The date SQL type.
///
/// This type is currently only implemented for PostgreSQL and SQLite.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`chrono::NaiveDate`][NaiveDate] with `feature = "chrono"`
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`chrono::NaiveDate`][NaiveDate] with `feature = "chrono"`
///
/// [NaiveDate]: /chrono/naive/date/struct.NaiveDate.html
#[derive(Debug, Clone, Copy, Default)] pub struct Date;

/// The interval SQL type.
///
/// This type is currently only implemented for PostgreSQL.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`PgInterval`][PgInterval] which can be constructed using the [interval
///   DSLs][interval dsls]
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`PgInterval`][PgInterval] which can be constructed using the [interval
///   DSLs][interval dsls]
///
/// [PgInterval]: /diesel/pg/data_types/struct.PgInterval.html
/// [interval dsls]: /diesel/pg/expression/extensions/index.html
#[derive(Debug, Clone, Copy, Default)] pub struct Interval;

/// The time SQL type.
///
/// This type is currently only implemented for PostgreSQL and SQLite.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`chrono::NaiveTime`][NaiveTime] with `feature = "chrono"`
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`chrono::NaiveTime`][NaiveTime] with `feature = "chrono"`
///
/// [NaiveTime]: /chrono/naive/time/struct.NaiveTime.html
#[derive(Debug, Clone, Copy, Default)] pub struct Time;

/// The timestamp/datetime SQL type.
///
/// This type is currently only implemented for PostgreSQL and SQLite.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - [`std::time::SystemTime`][SystemTime] (PG only)
/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
/// - [`time::Timespec`][Timespec] with `feature = "deprecated-time"` (PG only)
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - [`std::time::SystemTime`][SystemTime] (PG only)
/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
/// - [`time::Timespec`][Timespec] with `feature = "deprecated-time"` (PG only)
///
/// [SystemTime]: https://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html
/// [NaiveDateTime]: /chrono/naive/datetime/struct.NaiveDateTime.html
/// [Timespec]: /time/struct.Timespec.html
#[derive(Debug, Clone, Copy, Default)] pub struct Timestamp;

/// The nullable SQL type. This wraps another SQL type to indicate that it can
/// be null. By default all values are assumed to be `NOT NULL`.
///
/// ### [`ToSql`](/diesel/types/trait.ToSql.html) impls
///
/// - Any `T` which implements `ToSql<ST>`
/// - `Option<T>` for any `T` which implements `ToSql<ST>`
///
/// ### [`FromSql`](/diesel/types/trait.FromSql.html) impls
///
/// - `Option<T>` for any `T` which implements `FromSql<ST>`
#[derive(Debug, Clone, Copy, Default)] pub struct Nullable<ST: NotNull>(ST);

#[cfg(feature = "postgres")]
pub use pg::types::sql_types::*;

pub trait HasSqlType<ST>: TypeMetadata {
    fn metadata() -> Self::TypeMetadata;

    fn row_metadata(out: &mut Vec<Self::TypeMetadata>) {
        out.push(Self::metadata())
    }
}

pub trait NotNull {
}

pub trait IntoNullable {
    type Nullable;
}

impl<T: NotNull> IntoNullable for T {
    type Nullable = Nullable<T>;
}

impl<T: NotNull> IntoNullable for Nullable<T> {
    type Nullable = Nullable<T>;
}

/// How to deserialize a single field of a given type. The input will always be
/// the binary representation, not the text.
pub trait FromSql<A, DB: Backend + HasSqlType<A>>: Sized {
    fn from_sql(bytes: Option<&DB::RawValue>) -> Result<Self, Box<Error+Send+Sync>>;
}

/// How to deserialize multiple fields, with a known type. This type is
/// implemented for tuples of various sizes.
pub trait FromSqlRow<A, DB: Backend + HasSqlType<A>>: Sized {
    fn build_from_row<T: Row<DB>>(row: &mut T) -> Result<Self, Box<Error+Send+Sync>>;

    /// The number of fields that this type will consume. Should be equal to
    /// the number of times you would call `row.take()` in `build_from_row`
    fn fields_needed() -> usize {
        1
    }
}

#[cfg(feature = "unstable")]
impl<T, ST, DB> FromSqlRow<Nullable<ST>, DB> for Option<T> where
    T: FromSqlRow<ST, DB>,
    DB: Backend + HasSqlType<ST>,
    ST: NotNull,
{
    default fn build_from_row<R: Row<DB>>(row: &mut R) -> Result<Self, Box<Error+Send+Sync>> {
        if row.next_is_null(1) {
            row.take();
            Ok(None)
        } else {
            T::build_from_row(row).map(Some)
        }
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    Yes,
    No,
}

/// Serializes a single value to be sent to the database. The output will be
/// included as a bind parameter, and is expected to be the binary format, not
/// text.
pub trait ToSql<A, DB: Backend + HasSqlType<A>>: fmt::Debug {
    fn to_sql<W: Write>(&self, out: &mut W) -> Result<IsNull, Box<Error+Send+Sync>>;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T where
    DB: Backend + HasSqlType<A>,
    T: ToSql<A, DB>,
{
    fn to_sql<W: Write>(&self, out: &mut W) -> Result<IsNull, Box<Error+Send+Sync>> {
        (*self).to_sql(out)
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]

extern crate libc;

use pnet_sys;

pub const AF_LINK: libc::c_int = 18;

const IF_NAMESIZE: usize = 16;
const IFNAMSIZ: usize = IF_NAMESIZE;
const IOC_IN: libc::c_ulong = 0x80000000;
const IOC_OUT: libc::c_ulong = 0x40000000;
const IOC_INOUT: libc::c_ulong = IOC_IN | IOC_OUT;
const IOCPARM_SHIFT: libc::c_ulong = 13;
const IOCPARM_MASK: libc::c_ulong = (1 << (IOCPARM_SHIFT as usize)) - 1;

const SIZEOF_TIMEVAL: libc::c_ulong = 16;
const SIZEOF_IFREQ: libc::c_ulong = 32;
const SIZEOF_C_UINT: libc::c_ulong = 4;
#[cfg(target_os = "freebsd")]
const SIZEOF_C_LONG: libc::c_int = 8;

pub const BIOCSETIF: libc::c_ulong =
    IOC_IN | ((SIZEOF_IFREQ & IOCPARM_MASK) << 16usize) | (('B' as libc::c_ulong) << 8usize) | 108;
pub const BIOCIMMEDIATE: libc::c_ulong =
    IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 112;
pub const BIOCGBLEN: libc::c_ulong =
    IOC_OUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 102;
pub const BIOCGDLT: libc::c_ulong =
    IOC_OUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 106;

pub const BIOCSBLEN: libc::c_ulong =
    IOC_INOUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 102;
pub const BIOCSHDRCMPLT: libc::c_ulong =
    IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 117;
pub const BIOCSRTIMEOUT: libc::c_ulong =
    IOC_IN | ((SIZEOF_TIMEVAL & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 109;

#[cfg(target_os = "freebsd")]
pub const BIOCFEEDBACK: libc::c_ulong =
    IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 124;
// NOTE Could use BIOCSSEESENT on OS X, though set to 1 by default anyway

pub const DLT_NULL: libc::c_uint = 0;

#[cfg(target_os = "freebsd")]
const BPF_ALIGNMENT: libc::c_int = SIZEOF_C_LONG;
#[cfg(any(target_os = "openbsd", target_os = "macos", target_os = "ios", windows))]
const BPF_ALIGNMENT: libc::c_int = 4;

pub fn BPF_WORDALIGN(x: isize) -> isize {
    let bpf_alignment = BPF_ALIGNMENT as isize;
    (x + (bpf_alignment - 1)) & !(bpf_alignment - 1)
}

// See /usr/include/net/if.h
pub struct ifreq {
    pub ifr_name: [libc::c_char; IFNAMSIZ],
    pub ifru_addr: pnet_sys::SockAddr, // NOTE Should be a union
}

// See /usr/include/net/if_dl.h
// sdl_data does not match if_dl.h on OS X, since the size of 12 is a minimum.
// Will be unsafe
// when sdl_nlen > 40.
#[cfg(any(target_os = "openbsd", target_os = "freebsd", target_os = "macos", target_os = "ios"))]
pub struct sockaddr_dl {
    pub sdl_len: libc::c_uchar,
    pub sdl_family: libc::c_uchar,
    pub sdl_index: libc::c_ushort,
    pub sdl_type: libc::c_uchar,
    pub sdl_nlen: libc::c_uchar,
    pub sdl_alen: libc::c_uchar,
    pub sdl_slen: libc::c_uchar,
    pub sdl_data: [libc::c_char; 46],
}

// See man 4 bpf or /usr/include/net/bpf.h [windows: or Common/Packet32.h]
#[cfg(any(
    target_os = "freebsd",
    all(any(target_os = "macos", target_os = "ios"), target_pointer_width = "32"),
    windows
))]
#[repr(C)]
pub struct bpf_hdr {
    pub bh_tstamp: libc::timeval,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

pub struct timeval32 {
    pub tv_sec: i32,
    pub tv_usec: i32,
}

#[cfg(any(
    target_os = "openbsd",
    all(any(target_os = "macos", target_os = "ios"), target_pointer_width = "64")
))]
pub struct bpf_hdr {
    pub bh_tstamp: timeval32,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

#[cfg(not(windows))]
extern "C" {
    pub fn ioctl(d: libc::c_int, request: libc::c_ulong, ...) -> libc::c_int;
}
<commit_msg>Add #[repr(C)] of struct bpf_hdr for another target.<commit_after>// Copyright (c) 2014 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]

extern crate libc;

use pnet_sys;

pub const AF_LINK: libc::c_int = 18;

const IF_NAMESIZE: usize = 16;
const IFNAMSIZ: usize = IF_NAMESIZE;
const IOC_IN: libc::c_ulong = 0x80000000;
const IOC_OUT: libc::c_ulong = 0x40000000;
const IOC_INOUT: libc::c_ulong = IOC_IN | IOC_OUT;
const IOCPARM_SHIFT: libc::c_ulong = 13;
const IOCPARM_MASK: libc::c_ulong = (1 << (IOCPARM_SHIFT as usize)) - 1;

const SIZEOF_TIMEVAL: libc::c_ulong = 16;
const SIZEOF_IFREQ: libc::c_ulong = 32;
const SIZEOF_C_UINT: libc::c_ulong = 4;
#[cfg(target_os = "freebsd")]
const SIZEOF_C_LONG: libc::c_int = 8;

pub const BIOCSETIF: libc::c_ulong =
    IOC_IN | ((SIZEOF_IFREQ & IOCPARM_MASK) << 16usize) | (('B' as libc::c_ulong) << 8usize) | 108;
pub const BIOCIMMEDIATE: libc::c_ulong =
    IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 112;
pub const BIOCGBLEN: libc::c_ulong =
    IOC_OUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 102;
pub const BIOCGDLT: libc::c_ulong =
    IOC_OUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 106;

pub const BIOCSBLEN: libc::c_ulong =
    IOC_INOUT | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 102;
pub const BIOCSHDRCMPLT: libc::c_ulong =
    IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 117;
pub const BIOCSRTIMEOUT: libc::c_ulong =
    IOC_IN | ((SIZEOF_TIMEVAL & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 109;

#[cfg(target_os = "freebsd")]
pub const BIOCFEEDBACK: libc::c_ulong =
    IOC_IN | ((SIZEOF_C_UINT & IOCPARM_MASK) << 16) | (('B' as libc::c_ulong) << 8) | 124;
// NOTE Could use BIOCSSEESENT on OS X, though set to 1 by default anyway

pub const DLT_NULL: libc::c_uint = 0;

#[cfg(target_os = "freebsd")]
const BPF_ALIGNMENT: libc::c_int = SIZEOF_C_LONG;
#[cfg(any(target_os = "openbsd", target_os = "macos", target_os = "ios", windows))]
const BPF_ALIGNMENT: libc::c_int = 4;

pub fn BPF_WORDALIGN(x: isize) -> isize {
    let bpf_alignment = BPF_ALIGNMENT as isize;
    (x + (bpf_alignment - 1)) & !(bpf_alignment - 1)
}

// See /usr/include/net/if.h
pub struct ifreq {
    pub ifr_name: [libc::c_char; IFNAMSIZ],
    pub ifru_addr: pnet_sys::SockAddr, // NOTE Should be a union
}

// See /usr/include/net/if_dl.h
// sdl_data does not match if_dl.h on OS X, since the size of 12 is a minimum.
// Will be unsafe
// when sdl_nlen > 40.
#[cfg(any(target_os = "openbsd", target_os = "freebsd", target_os = "macos", target_os = "ios"))]
pub struct sockaddr_dl {
    pub sdl_len: libc::c_uchar,
    pub sdl_family: libc::c_uchar,
    pub sdl_index: libc::c_ushort,
    pub sdl_type: libc::c_uchar,
    pub sdl_nlen: libc::c_uchar,
    pub sdl_alen: libc::c_uchar,
    pub sdl_slen: libc::c_uchar,
    pub sdl_data: [libc::c_char; 46],
}

// See man 4 bpf or /usr/include/net/bpf.h [windows: or Common/Packet32.h]
#[cfg(any(
    target_os = "freebsd",
    all(any(target_os = "macos", target_os = "ios"), target_pointer_width = "32"),
    windows
))]
#[repr(C)]
pub struct bpf_hdr {
    pub bh_tstamp: libc::timeval,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

pub struct timeval32 {
    pub tv_sec: i32,
    pub tv_usec: i32,
}

#[cfg(any(
    target_os = "openbsd",
    all(any(target_os = "macos", target_os = "ios"), target_pointer_width = "64")
))]
#[repr(C)]
pub struct bpf_hdr {
    pub bh_tstamp: timeval32,
    pub bh_caplen: u32,
    pub bh_datalen: u32,
    pub bh_hdrlen: libc::c_ushort,
}

#[cfg(not(windows))]
extern "C" {
    pub fn ioctl(d: libc::c_int, request: libc::c_ulong, ...) -> libc::c_int;
}
<|endoftext|>


<commit_before>macro_rules! SAFE_READ_WRITE8 {
    ($value:ident, $addr:expr, $instruction:expr) => {{
        use cpu2::cpu::translate_address_write;
        use cpu2::memory::{read8, write8};
        match translate_address_write($addr) {
            Err(()) => {},
            Ok(phys_addr) => {
                let $value = read8(phys_addr);
                write8(phys_addr, $instruction);
            },
        }
    }};
}
macro_rules! SAFE_READ_WRITE16 {
    ($value:ident, $addr:expr, $instruction:expr) => {{
        use cpu2::cpu::{translate_address_write, virt_boundary_read16, virt_boundary_write16};
        use cpu2::memory::{read16, write16};
        match translate_address_write($addr) {
            Err(()) => {},
            Ok(phys_addr) => {
                if phys_addr & 0xFFF == 0xFFF {
                    match translate_address_write($addr + 1) {
                        Err(()) => {},
                        Ok(phys_addr_high) => {
                            let $value = virt_boundary_read16(phys_addr, phys_addr_high);
                            virt_boundary_write16(phys_addr, phys_addr_high, $instruction);
                        },
                    }
                }
                else {
                    let $value = read16(phys_addr);
                    write16(phys_addr, $instruction);
                }
            },
        }
    }};
}
macro_rules! SAFE_READ_WRITE32 {
    ($value:ident, $addr:expr, $instruction:expr) => {{
        use cpu2::cpu::{translate_address_write, virt_boundary_read32s, virt_boundary_write32};
        use cpu2::memory::{read32s, write32};
        match translate_address_write($addr) {
            Err(()) => {},
            Ok(phys_addr) => {
                if phys_addr & 0xFFF >= 0xFFD {
                    match translate_address_write($addr + 3 & !3) {
                        Err(()) => {},
                        Ok(phys_addr_high) => {
                            let phys_addr_high = phys_addr_high | ($addr as u32) + 3 & 3;
                            let $value = virt_boundary_read32s(phys_addr, phys_addr_high);
                            virt_boundary_write32(phys_addr, phys_addr_high, $instruction);
                        },
                    }
                }
                else {
                    let $value = read32s(phys_addr);
                    write32(phys_addr, $instruction);
                }
            },
        }
    }};
}
<commit_msg>Simplify<commit_after>macro_rules! SAFE_READ_WRITE8 {
    ($value:ident, $addr:expr, $instruction:expr) => {{
        use cpu2::cpu::translate_address_write;
        use cpu2::memory::{read8, write8};
        let phys_addr = return_on_pagefault!(translate_address_write($addr));
        let $value = read8(phys_addr);
        write8(phys_addr, $instruction);
    }};
}
macro_rules! SAFE_READ_WRITE16 {
    ($value:ident, $addr:expr, $instruction:expr) => {{
        use cpu2::cpu::{translate_address_write, virt_boundary_read16, virt_boundary_write16};
        use cpu2::memory::{read16, write16};
        let phys_addr = return_on_pagefault!(translate_address_write($addr));
        if phys_addr & 0xFFF == 0xFFF {
            let phys_addr_high = return_on_pagefault!(translate_address_write($addr + 1));
            let $value = virt_boundary_read16(phys_addr, phys_addr_high);
            virt_boundary_write16(phys_addr, phys_addr_high, $instruction);
        }
        else {
            let $value = read16(phys_addr);
            write16(phys_addr, $instruction);
        }
    }};
}
macro_rules! SAFE_READ_WRITE32 {
    ($value:ident, $addr:expr, $instruction:expr) => {{
        use cpu2::cpu::{translate_address_write, virt_boundary_read32s, virt_boundary_write32};
        use cpu2::memory::{read32s, write32};
        let phys_addr = return_on_pagefault!(translate_address_write($addr));
        if phys_addr & 0xFFF >= 0xFFD {
            let phys_addr_high = return_on_pagefault!(translate_address_write($addr + 3 & !3));
            let phys_addr_high = phys_addr_high | ($addr as u32) + 3 & 3;
            let $value = virt_boundary_read32s(phys_addr, phys_addr_high);
            virt_boundary_write32(phys_addr, phys_addr_high, $instruction);
        }
        else {
            let $value = read32s(phys_addr);
            write32(phys_addr, $instruction);
        }
    }};
}
<|endoftext|>


<commit_before>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct JobRequireVariable {
    id: i32,
    fk_job: i32,
    fk_variable: i32,
}

pub fn table_create_job_require_variable(conn: &Connection)  {
    conn.execute("CREATE TABLE JOB_REQUIRE_VARIABLE (
                  id                    INTEGER PRIMARY KEY ASC,
                  fk_job                INTEGER NOT NULL,
                  fk_variable           INTEGER NOT NULL,
                  FOREIGN KEY(fk_job) REFERENCES JOB(id) ON UPDATE CASCADE
                  FOREIGN KEY(fk_variable) REFERENCES JOB_REQUIRE_VARIABLE(id) ON UPDATE CASCADE
                  )", &[]).unwrap();
}

pub fn insert_job_require_variable(conn: &Connection, job: &i32, variable: &i32) -> Result<i32, &'static str> {
    let me = JobRequireVariable {
        id: 0,
        fk_job: *job,
        fk_variable: *variable,

    };
    let job_require_variable_instance = conn.execute("INSERT INTO JOB_REQUIRE_VARIABLE (fk_job, fk_variable)
                  VALUES (?1, ?2)",
                 &[&me.fk_job, &me.fk_variable]);
    if job_require_variable_instance.is_err() {
        return Err("Insert failed");
    }
    job_require_variable_instance.unwrap();
    return Ok(0);
}

pub fn list_job_require_variable(conn: &Connection)-> Vec<JobRequireVariable> {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable  FROM JOB_REQUIRE_VARIABLE").unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        JobRequireVariable {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    let mut items = Vec::<JobRequireVariable>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn job_require_variable_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable  FROM JOB_REQUIRE_VARIABLE").unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        JobRequireVariable {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found job_require_variable {:?}", person.unwrap());
    }
}

pub fn pk_job_require_variable_by_name(conn: &Connection, job: &i32, variable: &i32, pk: &mut i32) -> Result<i32, &'static str>{
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable  FROM JOB_REQUIRE_VARIABLE WHERE fk_job = ?1 AND fk_variable = ?2").unwrap();
    let job_require_variable_iter = stmt.query_map(&[job, variable], |row| {
        JobRequireVariable {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    if job_require_variable_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = job_require_variable_iter.unwrap();
    let mut found = 0;
    let mut items = Vec::<i32>::new();
    for person in result {
        let bill= person.unwrap();
        *pk = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}

<commit_msg>reformated with rustfmt<commit_after>use rusqlite::Connection;
use std::result;

#[derive(Debug)]
pub struct JobRequireVariable {
    id: i32,
    fk_job: i32,
    fk_variable: i32,
}

pub fn table_create_job_require_variable(conn: &Connection) {
    conn.execute(
        "CREATE TABLE JOB_REQUIRE_VARIABLE (
                  id                    INTEGER PRIMARY KEY ASC,
                  fk_job                INTEGER NOT NULL,
                  fk_variable           INTEGER NOT NULL,
                  FOREIGN KEY(fk_job) REFERENCES JOB(id) ON UPDATE CASCADE
                  FOREIGN KEY(fk_variable) REFERENCES JOB_REQUIRE_VARIABLE(id) ON UPDATE CASCADE
                  )",
        &[],
    ).unwrap();
}

pub fn insert_job_require_variable(
    conn: &Connection,
    job: &i32,
    variable: &i32,
) -> Result<i32, &'static str> {
    let me = JobRequireVariable {
        id: 0,
        fk_job: *job,
        fk_variable: *variable,
    };
    let job_require_variable_instance = conn.execute(
        "INSERT INTO JOB_REQUIRE_VARIABLE (fk_job, fk_variable)
                  VALUES (?1, ?2)",
        &[&me.fk_job, &me.fk_variable],
    );
    if job_require_variable_instance.is_err() {
        return Err("Insert failed");
    }
    job_require_variable_instance.unwrap();
    return Ok(0);
}

pub fn list_job_require_variable(conn: &Connection) -> Vec<JobRequireVariable> {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable  FROM JOB_REQUIRE_VARIABLE")
        .unwrap();
    let wraped_fs_file_iter = stmt.query_map(&[], |row| {
        JobRequireVariable {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    let mut items = Vec::<JobRequireVariable>::new();
    if wraped_fs_file_iter.is_err() {
        return items;

    }
    let fs_file_iter = wraped_fs_file_iter.unwrap();
    for person in fs_file_iter {

        items.push(person.unwrap());
    }
    return items;
}

pub fn job_require_variable_list(conn: &Connection) {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable  FROM JOB_REQUIRE_VARIABLE")
        .unwrap();
    let person_iter = stmt.query_map(&[], |row| {
        JobRequireVariable {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    }).unwrap();

    for person in person_iter {
        println!("Found job_require_variable {:?}", person.unwrap());
    }
}

pub fn pk_job_require_variable_by_name(
    conn: &Connection,
    job: &i32,
    variable: &i32,
    pk: &mut i32,
) -> Result<i32, &'static str> {
    let mut stmt = conn.prepare("SELECT id, fk_job, fk_variable  FROM JOB_REQUIRE_VARIABLE WHERE fk_job = ?1 AND fk_variable = ?2").unwrap();
    let job_require_variable_iter = stmt.query_map(&[job, variable], |row| {
        JobRequireVariable {
            id: row.get(0),
            fk_job: row.get(1),
            fk_variable: row.get(2),
        }
    });
    if job_require_variable_iter.is_err() {
        return Err("Insert failed dfdf");
    }
    let result = job_require_variable_iter.unwrap();
    let mut found = 0;
    let mut items = Vec::<i32>::new();
    for person in result {
        let bill = person.unwrap();
        *pk = bill.id;
        found = 1;
    }
    if found != 0 {
        return Ok(found);
    }
    return Err("None found");
}
<|endoftext|>


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

// Test inclusive range syntax.

#![feature(inclusive_range_syntax, inclusive_range, step_by)]

use std::ops::{RangeInclusive, RangeToInclusive};

fn foo() -> isize { 42 }

// Test that range syntax works in return statements
fn return_range_to() -> RangeToInclusive<i32> { return ...1; }

pub fn main() {
    let mut count = 0;
    for i in 0_usize...10 {
        assert!(i >= 0 && i <= 10);
        count += i;
    }
    assert_eq!(count, 55);

    let mut count = 0;
    let mut range = 0_usize...10;
    for i in range {
        assert!(i >= 0 && i <= 10);
        count += i;
    }
    assert_eq!(count, 55);

    let mut count = 0;
    for i in (0_usize...10).step_by(2) {
        assert!(i >= 0 && i <= 10 && i % 2 == 0);
        count += i;
    }
    assert_eq!(count, 30);

    let _ = 0_usize...4+4-3;
    let _ = 0...foo();

    let _ = { &42...&100 }; // references to literals are OK
    let _ = ...42_usize;

    // Test we can use two different types with a common supertype.
    let x = &42;
    {
        let y = 42;
        let _ = x...&y;
    }

    // test collection indexing
    let vec = (0...10).collect::<Vec<_>>();
    let slice: &[_] = &*vec;
    let string = String::from("hello world");
    let stir = "hello world";

    assert_eq!(&vec[3...6], &[3, 4, 5, 6]);
    assert_eq!(&vec[ ...6], &[0, 1, 2, 3, 4, 5, 6]);

    assert_eq!(&slice[3...6], &[3, 4, 5, 6]);
    assert_eq!(&slice[ ...6], &[0, 1, 2, 3, 4, 5, 6]);

    assert_eq!(&string[3...6], "lo w");
    assert_eq!(&string[ ...6], "hello w");

    assert_eq!(&stir[3...6], "lo w");
    assert_eq!(&stir[ ...6], "hello w");

    // test the size hints and emptying
    let mut long = 0...255u8;
    let mut short = 42...42;
    assert_eq!(long.size_hint(), (256, Some(256)));
    assert_eq!(short.size_hint(), (1, Some(1)));
    long.next();
    short.next();
    assert_eq!(long.size_hint(), (255, Some(255)));
    assert_eq!(short.size_hint(), (0, Some(0)));
    assert_eq!(short, RangeInclusive::Empty { at: 42 });

    assert_eq!(long.len(), 255);
    assert_eq!(short.len(), 0);

    // test iterating backwards
    assert_eq!(long.next_back(), Some(255));
    assert_eq!(long.next_back(), Some(254));
    assert_eq!(long.next_back(), Some(253));
    assert_eq!(long.next(), Some(1));
    assert_eq!(long.next(), Some(2));
    assert_eq!(long.next_back(), Some(252));
    for i in 3...251 {
        assert_eq!(long.next(), Some(i));
    }
    assert_eq!(long, RangeInclusive::Empty { at: 251 });

    // check underflow
    let mut narrow = 1...0;
    assert_eq!(narrow.next_back(), None);
    assert_eq!(narrow, RangeInclusive::Empty { at: 0 });

    // what happens if you have a nonsense range?
    let mut nonsense = 10...5;
    assert_eq!(nonsense.next(), None);
    assert_eq!(nonsense, RangeInclusive::Empty { at: 10 });

    // conversion
    assert_eq!(0...9, (0..10).into());
    assert_eq!(0...0, (0..1).into());
    assert_eq!(RangeInclusive::Empty { at: 1 }, (1..0).into());

    // output
    assert_eq!(format!("{:?}", 0...10), "0...10");
    assert_eq!(format!("{:?}", ...10), "...10");
    assert_eq!(format!("{:?}", long), "[empty range @ 251]");
}
<commit_msg>add underflow/overflow tests<commit_after>// Copyright 2016 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.

// Test inclusive range syntax.

#![feature(inclusive_range_syntax, inclusive_range, step_by)]

use std::ops::{RangeInclusive, RangeToInclusive};

fn foo() -> isize { 42 }

// Test that range syntax works in return statements
fn return_range_to() -> RangeToInclusive<i32> { return ...1; }

pub fn main() {
    let mut count = 0;
    for i in 0_usize...10 {
        assert!(i >= 0 && i <= 10);
        count += i;
    }
    assert_eq!(count, 55);

    let mut count = 0;
    let mut range = 0_usize...10;
    for i in range {
        assert!(i >= 0 && i <= 10);
        count += i;
    }
    assert_eq!(count, 55);

    let mut count = 0;
    for i in (0_usize...10).step_by(2) {
        assert!(i >= 0 && i <= 10 && i % 2 == 0);
        count += i;
    }
    assert_eq!(count, 30);

    let _ = 0_usize...4+4-3;
    let _ = 0...foo();

    let _ = { &42...&100 }; // references to literals are OK
    let _ = ...42_usize;

    // Test we can use two different types with a common supertype.
    let x = &42;
    {
        let y = 42;
        let _ = x...&y;
    }

    // test collection indexing
    let vec = (0...10).collect::<Vec<_>>();
    let slice: &[_] = &*vec;
    let string = String::from("hello world");
    let stir = "hello world";

    assert_eq!(&vec[3...6], &[3, 4, 5, 6]);
    assert_eq!(&vec[ ...6], &[0, 1, 2, 3, 4, 5, 6]);

    assert_eq!(&slice[3...6], &[3, 4, 5, 6]);
    assert_eq!(&slice[ ...6], &[0, 1, 2, 3, 4, 5, 6]);

    assert_eq!(&string[3...6], "lo w");
    assert_eq!(&string[ ...6], "hello w");

    assert_eq!(&stir[3...6], "lo w");
    assert_eq!(&stir[ ...6], "hello w");

    // test the size hints and emptying
    let mut long = 0...255u8;
    let mut short = 42...42;
    assert_eq!(long.size_hint(), (256, Some(256)));
    assert_eq!(short.size_hint(), (1, Some(1)));
    long.next();
    short.next();
    assert_eq!(long.size_hint(), (255, Some(255)));
    assert_eq!(short.size_hint(), (0, Some(0)));
    assert_eq!(short, RangeInclusive::Empty { at: 42 });

    assert_eq!(long.len(), 255);
    assert_eq!(short.len(), 0);

    // test iterating backwards
    assert_eq!(long.next_back(), Some(255));
    assert_eq!(long.next_back(), Some(254));
    assert_eq!(long.next_back(), Some(253));
    assert_eq!(long.next(), Some(1));
    assert_eq!(long.next(), Some(2));
    assert_eq!(long.next_back(), Some(252));
    for i in 3...251 {
        assert_eq!(long.next(), Some(i));
    }
    assert_eq!(long, RangeInclusive::Empty { at: 251 });

    // check underflow
    let mut narrow = 1...0;
    assert_eq!(narrow.next_back(), None);
    assert_eq!(narrow, RangeInclusive::Empty { at: 0 });
    let mut zero = 0u8...0;
    assert_eq!(zero.next_back(), Some(0));
    assert_eq!(zero.next_back(), None);
    assert_eq!(zero, RangeInclusive::Empty { at: 0 });
    let mut high = 255u8...255;
    assert_eq!(high.next_back(), Some(255));
    assert_eq!(high.next_back(), None);
    assert_eq!(high, RangeInclusive::Empty { at: 255 });

    // what happens if you have a nonsense range?
    let mut nonsense = 10...5;
    assert_eq!(nonsense.next(), None);
    assert_eq!(nonsense, RangeInclusive::Empty { at: 10 });

    // conversion
    assert_eq!(0...9, (0..10).into());
    assert_eq!(0...0, (0..1).into());
    assert_eq!(RangeInclusive::Empty { at: 1 }, (1..0).into());

    // output
    assert_eq!(format!("{:?}", 0...10), "0...10");
    assert_eq!(format!("{:?}", ...10), "...10");
    assert_eq!(format!("{:?}", long), "[empty range @ 251]");
}
<|endoftext|>


<commit_before>use crate::{
    conv, device::Device, native, Backend as B, GlContainer, PhysicalDevice, QueueFamily, Starc,
};
use glow::HasContext;
use hal::{adapter::Adapter, format as f, image, window};
use parking_lot::Mutex;
use std::sync::Arc;
use wasm_bindgen::JsCast;

#[derive(Clone, Debug)]
pub struct Swapchain {
    pub(crate) extent: window::Extent2D,
    pub(crate) channel: f::ChannelType,
    pub(crate) raw_format: native::TextureFormat,
    pub(crate) framebuffer: native::RawFramebuffer,
}

#[derive(Debug)]
pub struct Instance {
    canvas: Mutex<Option<Starc<web_sys::HtmlCanvasElement>>>,
}

impl hal::Instance<B> for Instance {
    fn create(_name: &str, _version: u32) -> Result<Self, hal::UnsupportedBackend> {
        Ok(Instance {
            canvas: Mutex::new(None),
        })
    }

    fn enumerate_adapters(&self) -> Vec<Adapter<B>> {
        let canvas_guard = self.canvas.lock();
        let context = match *canvas_guard {
            Some(ref canvas) => {
                // TODO: Remove hardcoded width/height
                if canvas.get_attribute("width").is_none() {
                    canvas
                        .set_attribute("width", "640")
                        .expect("Cannot set width");
                }
                if canvas.get_attribute("height").is_none() {
                    canvas
                        .set_attribute("height", "480")
                        .expect("Cannot set height");
                }
                let context_options = js_sys::Object::new();
                js_sys::Reflect::set(
                    &context_options,
                    &"antialias".into(),
                    &wasm_bindgen::JsValue::FALSE,
                )
                .expect("Cannot create context options");
                let webgl2_context = canvas
                    .get_context_with_context_options("webgl2", &context_options)
                    .expect("Cannot create WebGL2 context")
                    .and_then(|context| context.dyn_into::<web_sys::WebGl2RenderingContext>().ok())
                    .expect("Cannot convert into WebGL2 context");
                glow::Context::from_webgl2_context(webgl2_context)
            }
            None => return Vec::new(),
        };

        let adapter = PhysicalDevice::new_adapter(context);
        vec![adapter]
    }

    unsafe fn create_surface(
        &self,
        has_handle: &impl raw_window_handle::HasRawWindowHandle,
    ) -> Result<Surface, window::InitError> {
        if let raw_window_handle::RawWindowHandle::Web(handle) = has_handle.raw_window_handle() {
            let canvas: Starc<web_sys::HtmlCanvasElement> = Starc::new(
                web_sys::window()
                    .and_then(|win| win.document())
                    .expect("Cannot get document")
                    .query_selector(&format!("canvas[data-raw-handle=\"{}\"]", handle.id))
                    .expect("Cannot query for canvas")
                    .expect("Canvas is not found")
                    .dyn_into()
                    .expect("Failed to downcast to canvas type"),
            );

            *self.canvas.lock() = Some(canvas.clone());

            Ok(Surface {
                canvas,
                swapchain: None,
                renderbuffer: None,
            })
        } else {
            unreachable!()
        }
    }

    unsafe fn destroy_surface(&self, surface: Surface) {
        let mut canvas_option_ref = self.canvas.lock();

        if let Some(canvas) = canvas_option_ref.as_ref() {
            if Arc::ptr_eq(&canvas.arc, &surface.canvas.arc) {
                *canvas_option_ref = None;
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct Surface {
    canvas: Starc<web_sys::HtmlCanvasElement>,
    pub(crate) swapchain: Option<Swapchain>,
    renderbuffer: Option<native::Renderbuffer>,
}

impl Surface {
    fn swapchain_formats(&self) -> Vec<f::Format> {
        vec![f::Format::Rgba8Unorm, f::Format::Bgra8Unorm]
    }

    pub(crate) unsafe fn present(
        &mut self,
        _image: native::SwapchainImage,
        gl: &GlContainer,
    ) -> Result<Option<window::Suboptimal>, window::PresentError> {
        let swapchain = self.swapchain.as_ref().unwrap();

        gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None);
        gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(swapchain.framebuffer));
        gl.blit_framebuffer(
            0,
            0,
            swapchain.extent.width as _,
            swapchain.extent.height as _,
            0,
            0,
            swapchain.extent.width as _,
            swapchain.extent.height as _,
            glow::COLOR_BUFFER_BIT,
            glow::NEAREST,
        );
        gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);

        Ok(None)
    }
}

impl window::Surface<B> for Surface {
    fn supports_queue_family(&self, _: &QueueFamily) -> bool {
        true
    }

    fn capabilities(&self, _physical_device: &PhysicalDevice) -> window::SurfaceCapabilities {
        let extent = hal::window::Extent2D {
            width: self.canvas.width(),
            height: self.canvas.height(),
        };

        window::SurfaceCapabilities {
            present_modes: window::PresentMode::FIFO, //TODO
            composite_alpha_modes: window::CompositeAlphaMode::OPAQUE, //TODO
            image_count: 1..=1,
            current_extent: Some(extent),
            extents: extent..=extent,
            max_image_layers: 1,
            usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC,
        }
    }

    fn supported_formats(&self, _physical_device: &PhysicalDevice) -> Option<Vec<f::Format>> {
        Some(self.swapchain_formats())
    }
}

impl window::PresentationSurface<B> for Surface {
    type SwapchainImage = native::SwapchainImage;

    unsafe fn configure_swapchain(
        &mut self,
        device: &Device,
        config: window::SwapchainConfig,
    ) -> Result<(), window::SwapchainError> {
        let gl = &device.share.context;

        if let Some(swapchain) = self.swapchain.take() {
            // delete all frame buffers already allocated
            gl.delete_framebuffer(swapchain.framebuffer);
        }

        if self.renderbuffer.is_none() {
            self.renderbuffer = Some(gl.create_renderbuffer().unwrap());
        }

        let desc = conv::describe_format(config.format).unwrap();
        gl.bind_renderbuffer(glow::RENDERBUFFER, self.renderbuffer);
        gl.renderbuffer_storage(
            glow::RENDERBUFFER,
            desc.tex_internal,
            config.extent.width as i32,
            config.extent.height as i32,
        );

        let framebuffer = gl.create_framebuffer().unwrap();
        gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(framebuffer));
        gl.framebuffer_renderbuffer(
            glow::READ_FRAMEBUFFER,
            glow::COLOR_ATTACHMENT0,
            glow::RENDERBUFFER,
            self.renderbuffer,
        );
        self.swapchain = Some(Swapchain {
            extent: config.extent,
            channel: config.format.base_format().1,
            raw_format: desc.tex_external,
            framebuffer,
        });
        Ok(())
    }

    unsafe fn unconfigure_swapchain(&mut self, device: &Device) {
        let gl = &device.share.context;
        if let Some(swapchain) = self.swapchain.take() {
            gl.delete_framebuffer(swapchain.framebuffer);
        }
        if let Some(renderbuffer) = self.renderbuffer.take() {
            gl.delete_renderbuffer(renderbuffer);
        }
    }

    unsafe fn acquire_image(
        &mut self,
        _timeout_ns: u64,
    ) -> Result<(Self::SwapchainImage, Option<window::Suboptimal>), window::AcquireError> {
        let sc = self.swapchain.as_ref().unwrap();
        let swapchain_image = native::SwapchainImage::new(
            self.renderbuffer.unwrap(),
            sc.raw_format,
            sc.extent,
            sc.channel,
        );
        Ok((swapchain_image, None))
    }
}
<commit_msg>[WebGL] Return only RGBA swapchain formats<commit_after>use crate::{
    conv, device::Device, native, Backend as B, GlContainer, PhysicalDevice, QueueFamily, Starc,
};
use glow::HasContext;
use hal::{adapter::Adapter, format as f, image, window};
use parking_lot::Mutex;
use std::sync::Arc;
use wasm_bindgen::JsCast;

#[derive(Clone, Debug)]
pub struct Swapchain {
    pub(crate) extent: window::Extent2D,
    pub(crate) channel: f::ChannelType,
    pub(crate) raw_format: native::TextureFormat,
    pub(crate) framebuffer: native::RawFramebuffer,
}

#[derive(Debug)]
pub struct Instance {
    canvas: Mutex<Option<Starc<web_sys::HtmlCanvasElement>>>,
}

impl hal::Instance<B> for Instance {
    fn create(_name: &str, _version: u32) -> Result<Self, hal::UnsupportedBackend> {
        Ok(Instance {
            canvas: Mutex::new(None),
        })
    }

    fn enumerate_adapters(&self) -> Vec<Adapter<B>> {
        let canvas_guard = self.canvas.lock();
        let context = match *canvas_guard {
            Some(ref canvas) => {
                // TODO: Remove hardcoded width/height
                if canvas.get_attribute("width").is_none() {
                    canvas
                        .set_attribute("width", "640")
                        .expect("Cannot set width");
                }
                if canvas.get_attribute("height").is_none() {
                    canvas
                        .set_attribute("height", "480")
                        .expect("Cannot set height");
                }
                let context_options = js_sys::Object::new();
                js_sys::Reflect::set(
                    &context_options,
                    &"antialias".into(),
                    &wasm_bindgen::JsValue::FALSE,
                )
                .expect("Cannot create context options");
                let webgl2_context = canvas
                    .get_context_with_context_options("webgl2", &context_options)
                    .expect("Cannot create WebGL2 context")
                    .and_then(|context| context.dyn_into::<web_sys::WebGl2RenderingContext>().ok())
                    .expect("Cannot convert into WebGL2 context");
                glow::Context::from_webgl2_context(webgl2_context)
            }
            None => return Vec::new(),
        };

        let adapter = PhysicalDevice::new_adapter(context);
        vec![adapter]
    }

    unsafe fn create_surface(
        &self,
        has_handle: &impl raw_window_handle::HasRawWindowHandle,
    ) -> Result<Surface, window::InitError> {
        if let raw_window_handle::RawWindowHandle::Web(handle) = has_handle.raw_window_handle() {
            let canvas: Starc<web_sys::HtmlCanvasElement> = Starc::new(
                web_sys::window()
                    .and_then(|win| win.document())
                    .expect("Cannot get document")
                    .query_selector(&format!("canvas[data-raw-handle=\"{}\"]", handle.id))
                    .expect("Cannot query for canvas")
                    .expect("Canvas is not found")
                    .dyn_into()
                    .expect("Failed to downcast to canvas type"),
            );

            *self.canvas.lock() = Some(canvas.clone());

            Ok(Surface {
                canvas,
                swapchain: None,
                renderbuffer: None,
            })
        } else {
            unreachable!()
        }
    }

    unsafe fn destroy_surface(&self, surface: Surface) {
        let mut canvas_option_ref = self.canvas.lock();

        if let Some(canvas) = canvas_option_ref.as_ref() {
            if Arc::ptr_eq(&canvas.arc, &surface.canvas.arc) {
                *canvas_option_ref = None;
            }
        }
    }
}

#[derive(Clone, Debug)]
pub struct Surface {
    canvas: Starc<web_sys::HtmlCanvasElement>,
    pub(crate) swapchain: Option<Swapchain>,
    renderbuffer: Option<native::Renderbuffer>,
}

impl Surface {
    fn swapchain_formats(&self) -> Vec<f::Format> {
        vec![f::Format::Rgba8Srgb, f::Format::Rgba8Unorm]
    }

    pub(crate) unsafe fn present(
        &mut self,
        _image: native::SwapchainImage,
        gl: &GlContainer,
    ) -> Result<Option<window::Suboptimal>, window::PresentError> {
        let swapchain = self.swapchain.as_ref().unwrap();

        gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None);
        gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(swapchain.framebuffer));
        gl.blit_framebuffer(
            0,
            0,
            swapchain.extent.width as _,
            swapchain.extent.height as _,
            0,
            0,
            swapchain.extent.width as _,
            swapchain.extent.height as _,
            glow::COLOR_BUFFER_BIT,
            glow::NEAREST,
        );
        gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);

        Ok(None)
    }
}

impl window::Surface<B> for Surface {
    fn supports_queue_family(&self, _: &QueueFamily) -> bool {
        true
    }

    fn capabilities(&self, _physical_device: &PhysicalDevice) -> window::SurfaceCapabilities {
        let extent = hal::window::Extent2D {
            width: self.canvas.width(),
            height: self.canvas.height(),
        };

        window::SurfaceCapabilities {
            present_modes: window::PresentMode::FIFO, //TODO
            composite_alpha_modes: window::CompositeAlphaMode::OPAQUE, //TODO
            image_count: 1..=1,
            current_extent: Some(extent),
            extents: extent..=extent,
            max_image_layers: 1,
            usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC,
        }
    }

    fn supported_formats(&self, _physical_device: &PhysicalDevice) -> Option<Vec<f::Format>> {
        Some(self.swapchain_formats())
    }
}

impl window::PresentationSurface<B> for Surface {
    type SwapchainImage = native::SwapchainImage;

    unsafe fn configure_swapchain(
        &mut self,
        device: &Device,
        config: window::SwapchainConfig,
    ) -> Result<(), window::SwapchainError> {
        let gl = &device.share.context;

        if let Some(swapchain) = self.swapchain.take() {
            // delete all frame buffers already allocated
            gl.delete_framebuffer(swapchain.framebuffer);
        }

        if self.renderbuffer.is_none() {
            self.renderbuffer = Some(gl.create_renderbuffer().unwrap());
        }

        let desc = conv::describe_format(config.format).unwrap();
        gl.bind_renderbuffer(glow::RENDERBUFFER, self.renderbuffer);
        gl.renderbuffer_storage(
            glow::RENDERBUFFER,
            desc.tex_internal,
            config.extent.width as i32,
            config.extent.height as i32,
        );

        let framebuffer = gl.create_framebuffer().unwrap();
        gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(framebuffer));
        gl.framebuffer_renderbuffer(
            glow::READ_FRAMEBUFFER,
            glow::COLOR_ATTACHMENT0,
            glow::RENDERBUFFER,
            self.renderbuffer,
        );
        self.swapchain = Some(Swapchain {
            extent: config.extent,
            channel: config.format.base_format().1,
            raw_format: desc.tex_external,
            framebuffer,
        });
        Ok(())
    }

    unsafe fn unconfigure_swapchain(&mut self, device: &Device) {
        let gl = &device.share.context;
        if let Some(swapchain) = self.swapchain.take() {
            gl.delete_framebuffer(swapchain.framebuffer);
        }
        if let Some(renderbuffer) = self.renderbuffer.take() {
            gl.delete_renderbuffer(renderbuffer);
        }
    }

    unsafe fn acquire_image(
        &mut self,
        _timeout_ns: u64,
    ) -> Result<(Self::SwapchainImage, Option<window::Suboptimal>), window::AcquireError> {
        let sc = self.swapchain.as_ref().unwrap();
        let swapchain_image = native::SwapchainImage::new(
            self.renderbuffer.unwrap(),
            sc.raw_format,
            sc.extent,
            sc.channel,
        );
        Ok((swapchain_image, None))
    }
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate env_logger;
extern crate log;
extern crate webdriver;

use env_logger::LogBuilder;
use log::LogLevelFilter;
use std::env;
use webdriver::DriverSession;
use webdriver::firefox::GeckoDriver;

#[test]
fn test_file() {
    init_logging();

    let gecko = GeckoDriver::new().unwrap();
    let mut sess = DriverSession::new(gecko).unwrap();

    // `cargo test` starts with current directory set to the crate root.
    let crate_root =
        std::env::current_dir().unwrap()
        .to_str().unwrap().to_owned();
    let test_url = format!("file://{crate}/tests/integration_test.html", crate = crate_root);

    sess.go(&test_url).unwrap();
    let url = sess.get_current_url().unwrap();
    assert_eq!(url, test_url);

    let title = sess.get_title().unwrap();
    assert_eq!(title, "Test page title");

    sess.back().unwrap();
    sess.forward().unwrap();
    sess.refresh().unwrap();
    sess.get_page_source().unwrap();

    sess.get_cookies().unwrap();
    sess.get_window_handle().unwrap();
    {
        let handles = sess.get_window_handles().unwrap();
        assert_eq!(handles.len(), 1);
    }
    sess.close_window().unwrap();
}

fn init_logging() {
    let mut builder = LogBuilder::new();
    builder.filter(None, LogLevelFilter::Info);

    if let Ok(ev) = env::var("RUST_LOG") {
       builder.parse(&ev);
    }

    builder.init().unwrap();
}

mod youtube_integration_test {
    use webdriver::firefox::GeckoDriver;
    use webdriver::messages::LocationStrategy;
    use webdriver::DriverSession;

    #[test]
    #[ignore]
    fn test() {
        let gecko = GeckoDriver::new().unwrap();
        let mut sess = DriverSession::new(gecko).unwrap();
        sess.go("https://www.youtube.com/watch?v=dQw4w9WgXcQ").unwrap();
        sess.get_current_url().unwrap();
        sess.back().unwrap();
        sess.forward().unwrap();
        sess.refresh().unwrap();
        sess.get_page_source().unwrap();

        {
            let el = sess.find_element("a", LocationStrategy::Css).unwrap();
            el.attribute("href").unwrap();
            el.css_value("color").unwrap();
            el.text().unwrap();
            assert_eq!(el.name().unwrap(), "a");

            let imgs = sess.find_elements("img", LocationStrategy::Css).unwrap();
            for img in &imgs {
                println!("{}", img.attribute("src").unwrap());
            }

            sess.get_cookies().unwrap();
            sess.get_title().unwrap();
            sess.get_window_handle().unwrap();
            let handles = sess.get_window_handles().unwrap();
            assert_eq!(handles.len(), 1);
        }
        sess.close_window().unwrap();
    }
}
<commit_msg>Integration tests for session.execute().<commit_after>#![deny(warnings)]

extern crate env_logger;
extern crate log;
extern crate serde_json;
extern crate webdriver;

use env_logger::LogBuilder;
use log::LogLevelFilter;
use std::env;
use webdriver::DriverSession;
use webdriver::firefox::GeckoDriver;
use webdriver::messages::ExecuteCmd;

#[test]
fn test_file() {
    init_logging();

    let gecko = GeckoDriver::new().unwrap();
    let mut sess = DriverSession::new(gecko).unwrap();

    // `cargo test` starts with current directory set to the crate root.
    let crate_root =
        std::env::current_dir().unwrap()
        .to_str().unwrap().to_owned();
    let test_url = format!("file://{crate}/tests/integration_test.html", crate = crate_root);

    sess.go(&test_url).unwrap();
    let url = sess.get_current_url().unwrap();
    assert_eq!(url, test_url);

    let title = sess.get_title().unwrap();
    assert_eq!(title, "Test page title");

    sess.back().unwrap();
    sess.forward().unwrap();
    sess.refresh().unwrap();
    sess.get_page_source().unwrap();

    sess.get_cookies().unwrap();
    sess.get_window_handle().unwrap();
    {
        let handles = sess.get_window_handles().unwrap();
        assert_eq!(handles.len(), 1);
    }

    {
        // Test execute return
        let exec_json = sess.execute(ExecuteCmd {
            script: "return 2 + 2;".to_owned(),
            args: vec![],
        }).unwrap();
        let exec_int = serde_json::from_value::<i64>(exec_json).unwrap();
        assert_eq!(exec_int, 4);
    }

    {
        // Test execute handling an exception
        let exec_res = sess.execute(ExecuteCmd {
            script: "throw 'SomeException';".to_owned(),
            args: vec![],
        });
        assert!(exec_res.is_err());
        let err = exec_res.err().unwrap();
        let err = match err {
            webdriver::Error::WebDriverError(e) => e,
            _ => panic!("Unexpected error variant: {:#?}", err),
        };
        assert_eq!(err.message, "SomeException");
    }

    // TODO(alex): Test execute_async() success / failure.

    sess.close_window().unwrap();
}

fn init_logging() {
    let mut builder = LogBuilder::new();
    builder.filter(None, LogLevelFilter::Info);

    if let Ok(ev) = env::var("RUST_LOG") {
       builder.parse(&ev);
    }

    builder.init().unwrap();
}

mod youtube_integration_test {
    use webdriver::firefox::GeckoDriver;
    use webdriver::messages::LocationStrategy;
    use webdriver::DriverSession;

    #[test]
    #[ignore]
    fn test() {
        let gecko = GeckoDriver::new().unwrap();
        let mut sess = DriverSession::new(gecko).unwrap();
        sess.go("https://www.youtube.com/watch?v=dQw4w9WgXcQ").unwrap();
        sess.get_current_url().unwrap();
        sess.back().unwrap();
        sess.forward().unwrap();
        sess.refresh().unwrap();
        sess.get_page_source().unwrap();

        {
            let el = sess.find_element("a", LocationStrategy::Css).unwrap();
            el.attribute("href").unwrap();
            el.css_value("color").unwrap();
            el.text().unwrap();
            assert_eq!(el.name().unwrap(), "a");

            let imgs = sess.find_elements("img", LocationStrategy::Css).unwrap();
            for img in &imgs {
                println!("{}", img.attribute("src").unwrap());
            }

            sess.get_cookies().unwrap();
            sess.get_title().unwrap();
            sess.get_window_handle().unwrap();
            let handles = sess.get_window_handles().unwrap();
            assert_eq!(handles.len(), 1);
        }
        sess.close_window().unwrap();
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::iter;
use std::sync::Arc;
use format::ClearValue;
use framebuffer::AttachmentsList;
use framebuffer::FramebufferCreationError;
use framebuffer::RenderPassDesc;
use framebuffer::RenderPassDescAttachmentsList;
use framebuffer::RenderPassDescClearValues;
use framebuffer::LayoutAttachmentDescription;
use framebuffer::LayoutPassDescription;
use framebuffer::LayoutPassDependencyDescription;
use image::ImageViewAccess;

/// Description of an empty render pass.
///
/// Can be used to create a render pass with one subpass and no attachment.
///
/// # Example
///
/// ```
/// use vulkano::framebuffer::EmptySinglePassRenderPassDesc;
/// use vulkano::framebuffer::RenderPassDesc;
///
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
/// let rp = EmptySinglePassRenderPassDesc.build_render_pass(device.clone());
/// ```
///
/// # Clear value and attachments list
///
/// A render pass created from an `EmptySinglePassRenderPassDesc` accepts `()` for both the list
/// of attachments and the clear colors.
///
#[derive(Debug, Copy, Clone)]
pub struct EmptySinglePassRenderPassDesc;

unsafe impl RenderPassDesc for EmptySinglePassRenderPassDesc {
    #[inline]
    fn num_attachments(&self) -> usize {
        0
    }

    #[inline]
    fn attachment(&self, num: usize) -> Option<LayoutAttachmentDescription> {
        None
    }

    #[inline]
    fn num_subpasses(&self) -> usize {
        1
    }

    #[inline]
    fn subpass(&self, num: usize) -> Option<LayoutPassDescription> {
        if num == 0 {
            Some(LayoutPassDescription {
                color_attachments: vec![],
                depth_stencil: None,
                input_attachments: vec![],
                resolve_attachments: vec![],
                preserve_attachments: vec![],
            })
        } else {
            None
        }
    }

    #[inline]
    fn num_dependencies(&self) -> usize {
        0
    }

    #[inline]
    fn dependency(&self, num: usize) -> Option<LayoutPassDependencyDescription> {
        None
    }

    #[inline]
    fn num_color_attachments(&self, subpass: u32) -> Option<u32> {
        if subpass == 0 {
            Some(0)
        } else {
            None
        }
    }

    #[inline]
    fn num_samples(&self, _: u32) -> Option<u32> {
        None
    }

    #[inline]
    fn has_depth_stencil_attachment(&self, subpass: u32) -> Option<(bool, bool)> {
        if subpass == 0 {
            Some((false, false))
        } else {
            None
        }
    }

    #[inline]
    fn has_depth(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }

    #[inline]
    fn has_writable_depth(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }

    #[inline]
    fn has_stencil(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }

    #[inline]
    fn has_writable_stencil(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }
}

unsafe impl RenderPassDescAttachmentsList<Vec<Arc<ImageViewAccess + Send + Sync>>> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn check_attachments_list(&self, list: Vec<Arc<ImageViewAccess + Send + Sync>>) -> Result<Box<AttachmentsList + Send + Sync>, FramebufferCreationError> {
        if list.is_empty() {
            Ok(Box::new(()) as Box<_>)
        } else {
            panic!()        // FIXME: return error instead
        }
    }
}

unsafe impl RenderPassDescAttachmentsList<()> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn check_attachments_list(&self, list: ()) -> Result<Box<AttachmentsList + Send + Sync>, FramebufferCreationError> {
        Ok(Box::new(()) as Box<_>)
    }
}

unsafe impl RenderPassDescClearValues<Vec<ClearValue>> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn convert_clear_values(&self, values: Vec<ClearValue>) -> Box<Iterator<Item = ClearValue>> {
        assert!(values.is_empty());     // TODO: error instead
        Box::new(iter::empty())
    }
}

unsafe impl RenderPassDescClearValues<()> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn convert_clear_values(&self, values: ()) -> Box<Iterator<Item = ClearValue>> {
        Box::new(iter::empty())
    }
}
<commit_msg>Return an error in empty RP desc when using atchments<commit_after>// Copyright (c) 2016 The vulkano 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::iter;
use std::sync::Arc;
use format::ClearValue;
use framebuffer::AttachmentsList;
use framebuffer::FramebufferCreationError;
use framebuffer::RenderPassDesc;
use framebuffer::RenderPassDescAttachmentsList;
use framebuffer::RenderPassDescClearValues;
use framebuffer::LayoutAttachmentDescription;
use framebuffer::LayoutPassDescription;
use framebuffer::LayoutPassDependencyDescription;
use image::ImageViewAccess;

/// Description of an empty render pass.
///
/// Can be used to create a render pass with one subpass and no attachment.
///
/// # Example
///
/// ```
/// use vulkano::framebuffer::EmptySinglePassRenderPassDesc;
/// use vulkano::framebuffer::RenderPassDesc;
///
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
/// let rp = EmptySinglePassRenderPassDesc.build_render_pass(device.clone());
/// ```
///
/// # Clear value and attachments list
///
/// A render pass created from an `EmptySinglePassRenderPassDesc` accepts `()` for both the list
/// of attachments and the clear colors.
///
#[derive(Debug, Copy, Clone)]
pub struct EmptySinglePassRenderPassDesc;

unsafe impl RenderPassDesc for EmptySinglePassRenderPassDesc {
    #[inline]
    fn num_attachments(&self) -> usize {
        0
    }

    #[inline]
    fn attachment(&self, num: usize) -> Option<LayoutAttachmentDescription> {
        None
    }

    #[inline]
    fn num_subpasses(&self) -> usize {
        1
    }

    #[inline]
    fn subpass(&self, num: usize) -> Option<LayoutPassDescription> {
        if num == 0 {
            Some(LayoutPassDescription {
                color_attachments: vec![],
                depth_stencil: None,
                input_attachments: vec![],
                resolve_attachments: vec![],
                preserve_attachments: vec![],
            })
        } else {
            None
        }
    }

    #[inline]
    fn num_dependencies(&self) -> usize {
        0
    }

    #[inline]
    fn dependency(&self, num: usize) -> Option<LayoutPassDependencyDescription> {
        None
    }

    #[inline]
    fn num_color_attachments(&self, subpass: u32) -> Option<u32> {
        if subpass == 0 {
            Some(0)
        } else {
            None
        }
    }

    #[inline]
    fn num_samples(&self, _: u32) -> Option<u32> {
        None
    }

    #[inline]
    fn has_depth_stencil_attachment(&self, subpass: u32) -> Option<(bool, bool)> {
        if subpass == 0 {
            Some((false, false))
        } else {
            None
        }
    }

    #[inline]
    fn has_depth(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }

    #[inline]
    fn has_writable_depth(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }

    #[inline]
    fn has_stencil(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }

    #[inline]
    fn has_writable_stencil(&self, subpass: u32) -> Option<bool> {
        if subpass == 0 {
            Some(false)
        } else {
            None
        }
    }
}

unsafe impl RenderPassDescAttachmentsList<Vec<Arc<ImageViewAccess + Send + Sync>>> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn check_attachments_list(&self, list: Vec<Arc<ImageViewAccess + Send + Sync>>)
                              -> Result<Box<AttachmentsList + Send + Sync>, FramebufferCreationError>
    {
        if list.is_empty() {
            Ok(Box::new(()) as Box<_>)
        } else {
            Err(FramebufferCreationError::AttachmentsCountMismatch {
                expected: 0,
                obtained: list.len(),
            })
        }
    }
}

unsafe impl RenderPassDescAttachmentsList<()> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn check_attachments_list(&self, list: ()) -> Result<Box<AttachmentsList + Send + Sync>, FramebufferCreationError> {
        Ok(Box::new(()) as Box<_>)
    }
}

unsafe impl RenderPassDescClearValues<Vec<ClearValue>> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn convert_clear_values(&self, values: Vec<ClearValue>) -> Box<Iterator<Item = ClearValue>> {
        assert!(values.is_empty());     // TODO: error instead
        Box::new(iter::empty())
    }
}

unsafe impl RenderPassDescClearValues<()> for EmptySinglePassRenderPassDesc {
    #[inline]
    fn convert_clear_values(&self, values: ()) -> Box<Iterator<Item = ClearValue>> {
        Box::new(iter::empty())
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::iter;
use std::iter::Empty as EmptyIter;
use std::option::IntoIter as OptionIntoIter;
use std::sync::Arc;

use device::Device;
use format::ClearValue;
use framebuffer::framebuffer::FramebufferCreationError;
use framebuffer::sys::UnsafeRenderPass;
use framebuffer::traits::RenderPass;
use framebuffer::traits::RenderPassDesc;
use framebuffer::traits::RenderPassAttachmentsList;
use framebuffer::traits::RenderPassClearValues;
use framebuffer::traits::LayoutAttachmentDescription;
use framebuffer::traits::LayoutPassDescription;
use framebuffer::traits::LayoutPassDependencyDescription;
use image::Layout as ImageLayout;
use image::traits::Image;
use image::traits::ImageView;

use OomError;

/// Implementation of `RenderPass` with no attachment at all and a single pass.
///
/// When you use a `EmptySinglePassRenderPass`, the list of attachments and clear values must
/// be `()`.
pub struct EmptySinglePassRenderPass {
    render_pass: UnsafeRenderPass,
}

impl EmptySinglePassRenderPass {
    /// Builds the render pass.
    pub fn new(device: &Arc<Device>) -> Result<Arc<EmptySinglePassRenderPass>, OomError> {
        let rp = try!(unsafe {
            let pass = LayoutPassDescription {
                color_attachments: vec![],
                depth_stencil: None,
                input_attachments: vec![],
                resolve_attachments: vec![],
                preserve_attachments: vec![],
            };

            UnsafeRenderPass::new(device, iter::empty(), Some(pass).into_iter(), iter::empty())
        });

        Ok(Arc::new(EmptySinglePassRenderPass {
            render_pass: rp
        }))
    }
}

unsafe impl RenderPass for EmptySinglePassRenderPass {
    #[inline]
    fn render_pass(&self) -> &UnsafeRenderPass {
        &self.render_pass
    }
}

unsafe impl RenderPassDesc for EmptySinglePassRenderPass {
    type AttachmentsIter = EmptyIter<LayoutAttachmentDescription>;
    type PassesIter = OptionIntoIter<LayoutPassDescription>;
    type DependenciesIter = EmptyIter<LayoutPassDependencyDescription>;

    #[inline]
    fn attachments(&self) -> Self::AttachmentsIter {
        iter::empty()
    }

    #[inline]
    fn passes(&self) -> Self::PassesIter {
        Some(LayoutPassDescription {
            color_attachments: vec![],
            depth_stencil: None,
            input_attachments: vec![],
            resolve_attachments: vec![],
            preserve_attachments: vec![],
        }).into_iter()
    }

    #[inline]
    fn dependencies(&self) -> Self::DependenciesIter {
        iter::empty()
    }

    #[inline]
    fn num_subpasses(&self) -> u32 {
        1
    }

    #[inline]
    fn num_color_attachments(&self, subpass: u32) -> Option<u32> {
        if subpass == 0 {
            Some(0)
        } else {
            None
        }
    }
}

unsafe impl RenderPassAttachmentsList<()> for EmptySinglePassRenderPass {
    type AttachmentsIter = EmptyIter<(Arc<ImageView>, Arc<Image>, ImageLayout, ImageLayout)>;

    #[inline]
    fn convert_attachments_list(&self, _: ()) -> Self::AttachmentsIter {
        iter::empty()
    }
}

unsafe impl RenderPassClearValues<()> for EmptySinglePassRenderPass {
    type ClearValuesIter = EmptyIter<ClearValue>;

    #[inline]
    fn convert_clear_values(&self, _: ()) -> Self::ClearValuesIter {
        iter::empty()
    }
}
<commit_msg>Add small test for EmptyRenderPass<commit_after>// Copyright (c) 2016 The vulkano 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::iter;
use std::iter::Empty as EmptyIter;
use std::option::IntoIter as OptionIntoIter;
use std::sync::Arc;

use device::Device;
use format::ClearValue;
use framebuffer::sys::UnsafeRenderPass;
use framebuffer::traits::RenderPass;
use framebuffer::traits::RenderPassDesc;
use framebuffer::traits::RenderPassAttachmentsList;
use framebuffer::traits::RenderPassClearValues;
use framebuffer::traits::LayoutAttachmentDescription;
use framebuffer::traits::LayoutPassDescription;
use framebuffer::traits::LayoutPassDependencyDescription;
use image::Layout as ImageLayout;
use image::traits::Image;
use image::traits::ImageView;

use OomError;

/// Implementation of `RenderPass` with no attachment at all and a single pass.
///
/// When you use a `EmptySinglePassRenderPass`, the list of attachments and clear values must
/// be `()`.
pub struct EmptySinglePassRenderPass {
    render_pass: UnsafeRenderPass,
}

impl EmptySinglePassRenderPass {
    /// Builds the render pass.
    pub fn new(device: &Arc<Device>) -> Result<Arc<EmptySinglePassRenderPass>, OomError> {
        let rp = try!(unsafe {
            let pass = LayoutPassDescription {
                color_attachments: vec![],
                depth_stencil: None,
                input_attachments: vec![],
                resolve_attachments: vec![],
                preserve_attachments: vec![],
            };

            UnsafeRenderPass::new(device, iter::empty(), Some(pass).into_iter(), iter::empty())
        });

        Ok(Arc::new(EmptySinglePassRenderPass {
            render_pass: rp
        }))
    }
}

unsafe impl RenderPass for EmptySinglePassRenderPass {
    #[inline]
    fn render_pass(&self) -> &UnsafeRenderPass {
        &self.render_pass
    }
}

unsafe impl RenderPassDesc for EmptySinglePassRenderPass {
    type AttachmentsIter = EmptyIter<LayoutAttachmentDescription>;
    type PassesIter = OptionIntoIter<LayoutPassDescription>;
    type DependenciesIter = EmptyIter<LayoutPassDependencyDescription>;

    #[inline]
    fn attachments(&self) -> Self::AttachmentsIter {
        iter::empty()
    }

    #[inline]
    fn passes(&self) -> Self::PassesIter {
        Some(LayoutPassDescription {
            color_attachments: vec![],
            depth_stencil: None,
            input_attachments: vec![],
            resolve_attachments: vec![],
            preserve_attachments: vec![],
        }).into_iter()
    }

    #[inline]
    fn dependencies(&self) -> Self::DependenciesIter {
        iter::empty()
    }

    #[inline]
    fn num_subpasses(&self) -> u32 {
        1
    }

    #[inline]
    fn num_color_attachments(&self, subpass: u32) -> Option<u32> {
        if subpass == 0 {
            Some(0)
        } else {
            None
        }
    }

    #[inline]
    fn num_samples(&self, subpass: u32) -> Option<u32> {
        None
    }
}

unsafe impl RenderPassAttachmentsList<()> for EmptySinglePassRenderPass {
    type AttachmentsIter = EmptyIter<(Arc<ImageView>, Arc<Image>, ImageLayout, ImageLayout)>;

    #[inline]
    fn convert_attachments_list(&self, _: ()) -> Self::AttachmentsIter {
        iter::empty()
    }
}

unsafe impl RenderPassClearValues<()> for EmptySinglePassRenderPass {
    type ClearValuesIter = EmptyIter<ClearValue>;

    #[inline]
    fn convert_clear_values(&self, _: ()) -> Self::ClearValuesIter {
        iter::empty()
    }
}

#[cfg(test)]
mod tests {
    use framebuffer::EmptySinglePassRenderPass;

    #[test]
    fn create() {
        let (device, _) = gfx_dev_and_queue!();
        let _ = EmptySinglePassRenderPass::new(&device).unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>rgen3-string: Stop decoding string at terminator<commit_after><|endoftext|>