<commit_before>//! JSON and serialization
//!
//! # What is JSON?
//!
//! JSON (JavaScript Object Notation) is a way to write data in JavaScript.  Like XML, it allows to
//! encode structured data in a text format that can be easily read by humans.  Its simple syntax
//! and native compatibility with JavaScript have made it a widely used format.
//!
//! Data types that can be encoded are JavaScript types (see the `serde_json:Value` enum for more
//! details):
//!
//! * `Boolean`: equivalent to rust's `bool`
//! * `I64`: equivalent to rust's `i64`
//! * `U64`: equivalent to rust's `u64`
//! * `F64`: equivalent to rust's `f64`
//! * `String`: equivalent to rust's `String`
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
//!    same array
//! * `Object`: equivalent to rust's `BTreeMap<String, serde_json::Value>`; set the
//!    `preserve_order` feature to use `LinkedHashMap<String, serde_json::Value>` instead
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format.  Arrays are
//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).  A simple JSON
//! document encoding a person, his/her age, address and phone numbers could look like
//!
//! ```ignore
//! {
//!     "FirstName": "John",
//!     "LastName": "Doe",
//!     "Age": 43,
//!     "Address": {
//!         "Street": "Downing Street 10",
//!         "City": "London",
//!         "Country": "Great Britain"
//!     },
//!     "PhoneNumbers": [
//!         "+44 1234567",
//!         "+44 2345678"
//!     ]
//! }
//! ```
//!
//! If we assume that `FirstName` is optional and all other fields are mandatory, the above JSON could
//! correspond to the following Rust structs:
//!
//! ```ignore
//! #[derive(Serialize, Deserialize)]
//! struct Data {
//!     #[serde(rename="FirstName")] // to comply with Rust coding standards
//!     first_name: Option<String>,
//!     LastName: String,
//!     Age: u32,
//!     Address: Address,
//!     PhoneNumbers: Vec<String>
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Address {
//!     Street: String,
//!     City: String,
//!     Country: String
//! }
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from JSON via the serialization API.  To be able to serialize a piece of data, it must implement
//! the `serde::Serialize` trait.  To be able to deserialize a piece of data, it must implement the
//! `serde::Deserialize` trait.  Serde provides provides an annotation to automatically generate
//! the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! The JSON API also provides an enum `serde_json::Value` and a method `to_value` to serialize
//! objects.  A `serde_json::Value` value can be serialized as a string or buffer using the
//! functions described above.  You can also use the `json::Serializer` object, which implements the
//! `Serializer` trait.
//!
//! # Examples of use
//!
//! ## Parsing a `str` to `Value` and reading the result
//!
//! ```rust
//! extern crate serde_json;
//!
//! use serde_json::Value;
//!
//! fn main() {
//!     let data: Value = serde_json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//!     println!("data: {:?}", data);
//!     // data: {"bar":"baz","foo":13}
//!     println!("object? {}", data.is_object());
//!     // object? true
//!
//!     let obj = data.as_object().unwrap();
//!     let foo = obj.get("foo").unwrap();
//!
//!     println!("array? {:?}", foo.as_array());
//!     // array? None
//!     println!("u64? {:?}", foo.as_u64());
//!     // u64? Some(13u64)
//!
//!     for (key, value) in obj.iter() {
//!         println!("{}: {}", key, match *value {
//!             Value::U64(v) => format!("{} (u64)", v),
//!             Value::String(ref v) => format!("{} (string)", v),
//!             _ => format!("other")
//!         });
//!     }
//!     // bar: baz (string)
//!     // foo: 13 (u64)
//! }
//! ```

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", deny(clippy, clippy_pedantic))]
// Because of "JavaScript"... fixed in Manishearth/rust-clippy#1071
#![cfg_attr(feature = "clippy", allow(doc_markdown))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "clippy", allow(
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// string ser/de uses indexing and slicing
    indexing_slicing,
// things are often more readable this way
    shadow_reuse,
    shadow_unrelated,
    single_match_else,
    stutter,
// not practical
    missing_docs_in_private_items,
))]

#![deny(missing_docs)]

extern crate num_traits;
extern crate core;
#[macro_use]
extern crate serde;
extern crate itoa;
extern crate dtoa;
#[cfg(feature = "preserve_order")]
extern crate linked_hash_map;

pub use self::de::{Deserializer, StreamDeserializer, from_iter, from_reader,
                   from_slice, from_str};
pub use self::error::{Error, ErrorCode, Result};
pub use self::ser::{Serializer, escape_str, to_string, to_string_pretty,
                    to_vec, to_vec_pretty, to_writer, to_writer_pretty};
pub use self::value::{Map, Value, from_value, to_value};

pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;

mod read;
<commit_msg>Typo fixed: it's called Bool, not Boolean - cf https://docs.serde.rs/serde_json/value/enum.Value.html<commit_after>//! JSON and serialization
//!
//! # What is JSON?
//!
//! JSON (JavaScript Object Notation) is a way to write data in JavaScript.  Like XML, it allows to
//! encode structured data in a text format that can be easily read by humans.  Its simple syntax
//! and native compatibility with JavaScript have made it a widely used format.
//!
//! Data types that can be encoded are JavaScript types (see the `serde_json:Value` enum for more
//! details):
//!
//! * `Bool`: equivalent to rust's `bool`
//! * `I64`: equivalent to rust's `i64`
//! * `U64`: equivalent to rust's `u64`
//! * `F64`: equivalent to rust's `f64`
//! * `String`: equivalent to rust's `String`
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
//!    same array
//! * `Object`: equivalent to rust's `BTreeMap<String, serde_json::Value>`; set the
//!    `preserve_order` feature to use `LinkedHashMap<String, serde_json::Value>` instead
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format.  Arrays are
//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).  A simple JSON
//! document encoding a person, his/her age, address and phone numbers could look like
//!
//! ```ignore
//! {
//!     "FirstName": "John",
//!     "LastName": "Doe",
//!     "Age": 43,
//!     "Address": {
//!         "Street": "Downing Street 10",
//!         "City": "London",
//!         "Country": "Great Britain"
//!     },
//!     "PhoneNumbers": [
//!         "+44 1234567",
//!         "+44 2345678"
//!     ]
//! }
//! ```
//!
//! If we assume that `FirstName` is optional and all other fields are mandatory, the above JSON could
//! correspond to the following Rust structs:
//!
//! ```ignore
//! #[derive(Serialize, Deserialize)]
//! struct Data {
//!     #[serde(rename="FirstName")] // to comply with Rust coding standards
//!     first_name: Option<String>,
//!     LastName: String,
//!     Age: u32,
//!     Address: Address,
//!     PhoneNumbers: Vec<String>
//! }
//!
//! #[derive(Serialize, Deserialize)]
//! struct Address {
//!     Street: String,
//!     City: String,
//!     Country: String
//! }
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from JSON via the serialization API.  To be able to serialize a piece of data, it must implement
//! the `serde::Serialize` trait.  To be able to deserialize a piece of data, it must implement the
//! `serde::Deserialize` trait.  Serde provides provides an annotation to automatically generate
//! the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! The JSON API also provides an enum `serde_json::Value` and a method `to_value` to serialize
//! objects.  A `serde_json::Value` value can be serialized as a string or buffer using the
//! functions described above.  You can also use the `json::Serializer` object, which implements the
//! `Serializer` trait.
//!
//! # Examples of use
//!
//! ## Parsing a `str` to `Value` and reading the result
//!
//! ```rust
//! extern crate serde_json;
//!
//! use serde_json::Value;
//!
//! fn main() {
//!     let data: Value = serde_json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//!     println!("data: {:?}", data);
//!     // data: {"bar":"baz","foo":13}
//!     println!("object? {}", data.is_object());
//!     // object? true
//!
//!     let obj = data.as_object().unwrap();
//!     let foo = obj.get("foo").unwrap();
//!
//!     println!("array? {:?}", foo.as_array());
//!     // array? None
//!     println!("u64? {:?}", foo.as_u64());
//!     // u64? Some(13u64)
//!
//!     for (key, value) in obj.iter() {
//!         println!("{}: {}", key, match *value {
//!             Value::U64(v) => format!("{} (u64)", v),
//!             Value::String(ref v) => format!("{} (string)", v),
//!             _ => format!("other")
//!         });
//!     }
//!     // bar: baz (string)
//!     // foo: 13 (u64)
//! }
//! ```

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", deny(clippy, clippy_pedantic))]
// Because of "JavaScript"... fixed in Manishearth/rust-clippy#1071
#![cfg_attr(feature = "clippy", allow(doc_markdown))]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "clippy", allow(
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// string ser/de uses indexing and slicing
    indexing_slicing,
// things are often more readable this way
    shadow_reuse,
    shadow_unrelated,
    single_match_else,
    stutter,
// not practical
    missing_docs_in_private_items,
))]

#![deny(missing_docs)]

extern crate num_traits;
extern crate core;
#[macro_use]
extern crate serde;
extern crate itoa;
extern crate dtoa;
#[cfg(feature = "preserve_order")]
extern crate linked_hash_map;

pub use self::de::{Deserializer, StreamDeserializer, from_iter, from_reader,
                   from_slice, from_str};
pub use self::error::{Error, ErrorCode, Result};
pub use self::ser::{Serializer, escape_str, to_string, to_string_pretty,
                    to_vec, to_vec_pretty, to_writer, to_writer_pretty};
pub use self::value::{Map, Value, from_value, to_value};

pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;

mod read;
<|endoftext|>


<commit_before>pub const PCRE_CASELESS: int          = 0x00000001; // Compile
pub const PCRE_MULTILINE: int         = 0x00000002; // Compile
pub const PCRE_DOTALL: int            = 0x00000004; // Compile
pub const PCRE_EXTENDED: int          = 0x00000008; // Compile
pub const PCRE_ANCHORED: int          = 0x00000010; // Compile, exec, DFA exec
pub const PCRE_DOLLAR_ENDONLY: int    = 0x00000020; // Compile
pub const PCRE_EXTRA: int             = 0x00000040; // Compile
pub const PCRE_NOTBOL: int            = 0x00000080; // Exec, DFA exec
pub const PCRE_NOTEOL: int            = 0x00000100; // Exec, DFA exec
pub const PCRE_UNGREEDY: int          = 0x00000200; // Compile
pub const PCRE_NOTEMPTY: int          = 0x00000400; // Exec, DFA exec
pub const PCRE_UTF8: int              = 0x00000800; // Compile
pub const PCRE_NO_AUTO_CAPTURE: int   = 0x00001000; // Compile
pub const PCRE_NO_UTF8_CHECK: int     = 0x00002000; // Compile, exec, DFA exec
pub const PCRE_AUTO_CALLOUT: int      = 0x00004000; // Compile
pub const PCRE_PARTIAL_SOFT: int      = 0x00008000; // Exec, DFA exec
pub const PCRE_PARTIAL: int           = 0x00008000; // Backwards compatible synonym
pub const PCRE_DFA_SHORTEST: int      = 0x00010000; // DFA exec
pub const PCRE_DFA_RESTART: int       = 0x00020000; // DFA exec
pub const PCRE_FIRSTLINE: int         = 0x00040000; // Compile
pub const PCRE_DUPNAMES: int          = 0x00080000; // Compile
pub const PCRE_NEWLINE_CR: int        = 0x00100000; // Compile, exec, DFA exec
pub const PCRE_NEWLINE_LF: int        = 0x00200000; // Compile, exec, DFA exec
pub const PCRE_NEWLINE_CRLF: int      = 0x00300000; // Compile, exec, DFA exec
pub const PCRE_NEWLINE_ANY: int       = 0x00400000; // Compile, exec, DFA exec
pub const PCRE_NEWLINE_ANYCRLF: int   = 0x00500000; // Compile, exec, DFA exec
pub const PCRE_BSR_ANYCRLF: int       = 0x00800000; // Compile, exec, DFA exec
pub const PCRE_BSR_UNICODE: int       = 0x01000000; // Compile, exec, DFA exec
pub const PCRE_JAVASCRIPT_COMPAT: int = 0x02000000; // Compile
pub const PCRE_NO_START_OPTIMIZE: int = 0x04000000; // Compile, exec, DFA exec
pub const PCRE_NO_START_OPTIMISE: int = 0x04000000; // Synonym
pub const PCRE_PARTIAL_HARD: int      = 0x08000000; // Exec, DFA exec
pub const PCRE_NOTEMPTY_ATSTART: int  = 0x10000000; // Exec, DFA exec
pub const PCRE_UCP: int               = 0x20000000; // Compile

pub const COMPILE_OPTIONS: int        = 0x27fc7a7f;
pub const EXEC_OPTIONS: int           = 0x1df0a590;

//const COMPILE_OPTIONS: int =
//    PCRE_CASELESS
//  | PCRE_MULTILINE
//  | PCRE_DOTALL
//  | PCRE_EXTENDED
//  | PCRE_ANCHORED
//  | PCRE_DOLLAR_ENDONLY
//  | PCRE_EXTRA
//  | PCRE_UNGREEDY
//  | PCRE_UTF8
//  | PCRE_NO_AUTO_CAPTURE
//  | PCRE_NO_UTF8_CHECK
//  | PCRE_AUTO_CALLOUT
//  | PCRE_FIRSTLINE
//  | PCRE_DUPNAMES
//  | PCRE_NEWLINE_CR
//  | PCRE_NEWLINE_LF
//  | PCRE_NEWLINE_CRLF
//  | PCRE_NEWLINE_ANY
//  | PCRE_NEWLINE_ANYCRLF
//  | PCRE_BSR_ANYCRLF
//  | PCRE_BSR_UNICODE
//  | PCRE_JAVASCRIPT_COMPAT
//  | PCRE_NO_START_OPTIMIZE
//  | PCRE_NO_START_OPTIMISE
//  | PCRE_UCP;

//const EXEC_OPTIONS: int =
//    PCRE_ANCHORED
//  | PCRE_NOTBOL
//  | PCRE_NOTEOL
//  | PCRE_NOTEMPTY
//  | PCRE_NO_UTF8_CHECK
//  | PCRE_PARTIAL_SOFT
//  | PCRE_PARTIAL
//  | PCRE_NEWLINE_CR
//  | PCRE_NEWLINE_LF
//  | PCRE_NEWLINE_CRLF
//  | PCRE_NEWLINE_ANY
//  | PCRE_NEWLINE_ANYCRLF
//  | PCRE_BSR_ANYCRLF
//  | PCRE_BSR_UNICODE
//  | PCRE_NO_START_OPTIMIZE
//  | PCRE_NO_START_OPTIMISE
//  | PCRE_PARTIAL_HARD
//  | PCRE_NOTEMPTY_ATSTART;

pub const PCRE_ERROR_NOMATCH: int        =  -1;
pub const PCRE_ERROR_NULL: int           =  -2;
pub const PCRE_ERROR_BADOPTION: int      =  -3;
pub const PCRE_ERROR_BADMAGIC: int       =  -4;
pub const PCRE_ERROR_UNKNOWN_OPCODE: int =  -5;
pub const PCRE_ERROR_UNKNOWN_NODE: int   =  -5;  // For backward compatibility
pub const PCRE_ERROR_NOMEMORY: int       =  -6;
pub const PCRE_ERROR_NOSUBSTRING: int    =  -7;
pub const PCRE_ERROR_MATCHLIMIT: int     =  -8;
pub const PCRE_ERROR_CALLOUT: int        =  -9;  // Never used by PCRE itself
pub const PCRE_ERROR_BADUTF8: int        = -10;
pub const PCRE_ERROR_BADUTF8_OFFSET: int = -11;
pub const PCRE_ERROR_PARTIAL: int        = -12;
pub const PCRE_ERROR_BADPARTIAL: int     = -13;
pub const PCRE_ERROR_INTERNAL: int       = -14;
pub const PCRE_ERROR_BADCOUNT: int       = -15;
pub const PCRE_ERROR_DFA_UITEM: int      = -16;
pub const PCRE_ERROR_DFA_UCOND: int      = -17;
pub const PCRE_ERROR_DFA_UMLIMIT: int    = -18;
pub const PCRE_ERROR_DFA_WSSIZE: int     = -19;
pub const PCRE_ERROR_DFA_RECURSE: int    = -20;
pub const PCRE_ERROR_RECURSIONLIMIT: int = -21;
pub const PCRE_ERROR_NULLWSLIMIT: int    = -22;  // No longer actually used
pub const PCRE_ERROR_BADNEWLINE: int     = -23;
pub const PCRE_ERROR_BADOFFSET: int      = -24;
pub const PCRE_ERROR_SHORTUTF8: int      = -25;

pub const PCRE_INFO_OPTIONS: int         =   0;
pub const PCRE_INFO_SIZE: int            =   1;
pub const PCRE_INFO_CAPTURECOUNT: int    =   2;
pub const PCRE_INFO_BACKREFMAX: int      =   3;
pub const PCRE_INFO_FIRSTBYTE: int       =   4;
pub const PCRE_INFO_FIRSTCHAR: int       =   4; // For backwards compatibility
pub const PCRE_INFO_FIRSTTABLE: int      =   5;
pub const PCRE_INFO_LASTLITERAL: int     =   6;
pub const PCRE_INFO_NAMEENTRYSIZE: int   =   7;
pub const PCRE_INFO_NAMECOUNT: int       =   8;
pub const PCRE_INFO_NAMETABLE: int       =   9;
pub const PCRE_INFO_STUDYSIZE: int       =  10;
pub const PCRE_INFO_DEFAULT_TABLES: int  =  11;
pub const PCRE_INFO_OKPARTIAL: int       =  12;
pub const PCRE_INFO_JCHANGED: int        =  13;
pub const PCRE_INFO_HASCRORLF: int       =  14;
pub const PCRE_INFO_MINLENGTH: int       =  15;
<commit_msg>s/const/static/<commit_after>pub static PCRE_CASELESS: int          = 0x00000001; // Compile
pub static PCRE_MULTILINE: int         = 0x00000002; // Compile
pub static PCRE_DOTALL: int            = 0x00000004; // Compile
pub static PCRE_EXTENDED: int          = 0x00000008; // Compile
pub static PCRE_ANCHORED: int          = 0x00000010; // Compile, exec, DFA exec
pub static PCRE_DOLLAR_ENDONLY: int    = 0x00000020; // Compile
pub static PCRE_EXTRA: int             = 0x00000040; // Compile
pub static PCRE_NOTBOL: int            = 0x00000080; // Exec, DFA exec
pub static PCRE_NOTEOL: int            = 0x00000100; // Exec, DFA exec
pub static PCRE_UNGREEDY: int          = 0x00000200; // Compile
pub static PCRE_NOTEMPTY: int          = 0x00000400; // Exec, DFA exec
pub static PCRE_UTF8: int              = 0x00000800; // Compile
pub static PCRE_NO_AUTO_CAPTURE: int   = 0x00001000; // Compile
pub static PCRE_NO_UTF8_CHECK: int     = 0x00002000; // Compile, exec, DFA exec
pub static PCRE_AUTO_CALLOUT: int      = 0x00004000; // Compile
pub static PCRE_PARTIAL_SOFT: int      = 0x00008000; // Exec, DFA exec
pub static PCRE_PARTIAL: int           = 0x00008000; // Backwards compatible synonym
pub static PCRE_DFA_SHORTEST: int      = 0x00010000; // DFA exec
pub static PCRE_DFA_RESTART: int       = 0x00020000; // DFA exec
pub static PCRE_FIRSTLINE: int         = 0x00040000; // Compile
pub static PCRE_DUPNAMES: int          = 0x00080000; // Compile
pub static PCRE_NEWLINE_CR: int        = 0x00100000; // Compile, exec, DFA exec
pub static PCRE_NEWLINE_LF: int        = 0x00200000; // Compile, exec, DFA exec
pub static PCRE_NEWLINE_CRLF: int      = 0x00300000; // Compile, exec, DFA exec
pub static PCRE_NEWLINE_ANY: int       = 0x00400000; // Compile, exec, DFA exec
pub static PCRE_NEWLINE_ANYCRLF: int   = 0x00500000; // Compile, exec, DFA exec
pub static PCRE_BSR_ANYCRLF: int       = 0x00800000; // Compile, exec, DFA exec
pub static PCRE_BSR_UNICODE: int       = 0x01000000; // Compile, exec, DFA exec
pub static PCRE_JAVASCRIPT_COMPAT: int = 0x02000000; // Compile
pub static PCRE_NO_START_OPTIMIZE: int = 0x04000000; // Compile, exec, DFA exec
pub static PCRE_NO_START_OPTIMISE: int = 0x04000000; // Synonym
pub static PCRE_PARTIAL_HARD: int      = 0x08000000; // Exec, DFA exec
pub static PCRE_NOTEMPTY_ATSTART: int  = 0x10000000; // Exec, DFA exec
pub static PCRE_UCP: int               = 0x20000000; // Compile

pub static COMPILE_OPTIONS: int        = 0x27fc7a7f;
pub static EXEC_OPTIONS: int           = 0x1df0a590;

//static COMPILE_OPTIONS: int =
//    PCRE_CASELESS
//  | PCRE_MULTILINE
//  | PCRE_DOTALL
//  | PCRE_EXTENDED
//  | PCRE_ANCHORED
//  | PCRE_DOLLAR_ENDONLY
//  | PCRE_EXTRA
//  | PCRE_UNGREEDY
//  | PCRE_UTF8
//  | PCRE_NO_AUTO_CAPTURE
//  | PCRE_NO_UTF8_CHECK
//  | PCRE_AUTO_CALLOUT
//  | PCRE_FIRSTLINE
//  | PCRE_DUPNAMES
//  | PCRE_NEWLINE_CR
//  | PCRE_NEWLINE_LF
//  | PCRE_NEWLINE_CRLF
//  | PCRE_NEWLINE_ANY
//  | PCRE_NEWLINE_ANYCRLF
//  | PCRE_BSR_ANYCRLF
//  | PCRE_BSR_UNICODE
//  | PCRE_JAVASCRIPT_COMPAT
//  | PCRE_NO_START_OPTIMIZE
//  | PCRE_NO_START_OPTIMISE
//  | PCRE_UCP;

//static EXEC_OPTIONS: int =
//    PCRE_ANCHORED
//  | PCRE_NOTBOL
//  | PCRE_NOTEOL
//  | PCRE_NOTEMPTY
//  | PCRE_NO_UTF8_CHECK
//  | PCRE_PARTIAL_SOFT
//  | PCRE_PARTIAL
//  | PCRE_NEWLINE_CR
//  | PCRE_NEWLINE_LF
//  | PCRE_NEWLINE_CRLF
//  | PCRE_NEWLINE_ANY
//  | PCRE_NEWLINE_ANYCRLF
//  | PCRE_BSR_ANYCRLF
//  | PCRE_BSR_UNICODE
//  | PCRE_NO_START_OPTIMIZE
//  | PCRE_NO_START_OPTIMISE
//  | PCRE_PARTIAL_HARD
//  | PCRE_NOTEMPTY_ATSTART;

pub static PCRE_ERROR_NOMATCH: int        =  -1;
pub static PCRE_ERROR_NULL: int           =  -2;
pub static PCRE_ERROR_BADOPTION: int      =  -3;
pub static PCRE_ERROR_BADMAGIC: int       =  -4;
pub static PCRE_ERROR_UNKNOWN_OPCODE: int =  -5;
pub static PCRE_ERROR_UNKNOWN_NODE: int   =  -5;  // For backward compatibility
pub static PCRE_ERROR_NOMEMORY: int       =  -6;
pub static PCRE_ERROR_NOSUBSTRING: int    =  -7;
pub static PCRE_ERROR_MATCHLIMIT: int     =  -8;
pub static PCRE_ERROR_CALLOUT: int        =  -9;  // Never used by PCRE itself
pub static PCRE_ERROR_BADUTF8: int        = -10;
pub static PCRE_ERROR_BADUTF8_OFFSET: int = -11;
pub static PCRE_ERROR_PARTIAL: int        = -12;
pub static PCRE_ERROR_BADPARTIAL: int     = -13;
pub static PCRE_ERROR_INTERNAL: int       = -14;
pub static PCRE_ERROR_BADCOUNT: int       = -15;
pub static PCRE_ERROR_DFA_UITEM: int      = -16;
pub static PCRE_ERROR_DFA_UCOND: int      = -17;
pub static PCRE_ERROR_DFA_UMLIMIT: int    = -18;
pub static PCRE_ERROR_DFA_WSSIZE: int     = -19;
pub static PCRE_ERROR_DFA_RECURSE: int    = -20;
pub static PCRE_ERROR_RECURSIONLIMIT: int = -21;
pub static PCRE_ERROR_NULLWSLIMIT: int    = -22;  // No longer actually used
pub static PCRE_ERROR_BADNEWLINE: int     = -23;
pub static PCRE_ERROR_BADOFFSET: int      = -24;
pub static PCRE_ERROR_SHORTUTF8: int      = -25;

pub static PCRE_INFO_OPTIONS: int         =   0;
pub static PCRE_INFO_SIZE: int            =   1;
pub static PCRE_INFO_CAPTURECOUNT: int    =   2;
pub static PCRE_INFO_BACKREFMAX: int      =   3;
pub static PCRE_INFO_FIRSTBYTE: int       =   4;
pub static PCRE_INFO_FIRSTCHAR: int       =   4; // For backwards compatibility
pub static PCRE_INFO_FIRSTTABLE: int      =   5;
pub static PCRE_INFO_LASTLITERAL: int     =   6;
pub static PCRE_INFO_NAMEENTRYSIZE: int   =   7;
pub static PCRE_INFO_NAMECOUNT: int       =   8;
pub static PCRE_INFO_NAMETABLE: int       =   9;
pub static PCRE_INFO_STUDYSIZE: int       =  10;
pub static PCRE_INFO_DEFAULT_TABLES: int  =  11;
pub static PCRE_INFO_OKPARTIAL: int       =  12;
pub static PCRE_INFO_JCHANGED: int        =  13;
pub static PCRE_INFO_HASCRORLF: int       =  14;
pub static PCRE_INFO_MINLENGTH: int       =  15;
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use ReferrerPolicy;
use hyper::header::Headers;
use hyper::method::Method;
use msg::constellation_msg::PipelineId;
use servo_url::{ImmutableOrigin, ServoUrl};
use std::default::Default;

/// An [initiator](https://fetch.spec.whatwg.org/#concept-request-initiator)
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum Initiator {
    None,
    Download,
    ImageSet,
    Manifest,
    XSLT,
}

/// A request [type](https://fetch.spec.whatwg.org/#concept-request-type)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum Type {
    None,
    Audio,
    Font,
    Image,
    Script,
    Style,
    Track,
    Video,
}

/// A request [destination](https://fetch.spec.whatwg.org/#concept-request-destination)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum Destination {
    None,
    Document,
    Embed,
    Font,
    Image,
    Manifest,
    Media,
    Object,
    Report,
    Script,
    ServiceWorker,
    SharedWorker,
    Style,
    Worker,
    XSLT,
}

/// A request [origin](https://fetch.spec.whatwg.org/#concept-request-origin)
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, HeapSizeOf)]
pub enum Origin {
    Client,
    Origin(ImmutableOrigin),
}

/// A [referer](https://fetch.spec.whatwg.org/#concept-request-referrer)
#[derive(Clone, PartialEq, HeapSizeOf)]
pub enum Referrer {
    NoReferrer,
    /// Default referrer if nothing is specified
    Client,
    ReferrerUrl(ServoUrl),
}

/// A [request mode](https://fetch.spec.whatwg.org/#concept-request-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum RequestMode {
    Navigate,
    SameOrigin,
    NoCors,
    CorsMode,
    WebSocket
}

/// Request [credentials mode](https://fetch.spec.whatwg.org/#concept-request-credentials-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum CredentialsMode {
    Omit,
    CredentialsSameOrigin,
    Include,
}

/// [Cache mode](https://fetch.spec.whatwg.org/#concept-request-cache-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum CacheMode {
    Default,
    NoStore,
    Reload,
    NoCache,
    ForceCache,
    OnlyIfCached,
}

/// [Redirect mode](https://fetch.spec.whatwg.org/#concept-request-redirect-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum RedirectMode {
    Follow,
    Error,
    Manual,
}

/// [Response tainting](https://fetch.spec.whatwg.org/#concept-request-response-tainting)
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum ResponseTainting {
    Basic,
    CorsTainting,
    Opaque,
}

/// [Window](https://fetch.spec.whatwg.org/#concept-request-window)
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum Window {
    NoWindow,
    Client, // TODO: Environmental settings object
}

/// [CORS settings attribute](https://html.spec.whatwg.org/multipage/#attr-crossorigin-anonymous)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum CorsSettings {
    Anonymous,
    UseCredentials,
}

#[derive(Serialize, Deserialize, Clone, HeapSizeOf)]
pub struct RequestInit {
    #[serde(deserialize_with = "::hyper_serde::deserialize",
            serialize_with = "::hyper_serde::serialize")]
    #[ignore_heap_size_of = "Defined in hyper"]
    pub method: Method,
    pub url: ServoUrl,
    #[serde(deserialize_with = "::hyper_serde::deserialize",
            serialize_with = "::hyper_serde::serialize")]
    #[ignore_heap_size_of = "Defined in hyper"]
    pub headers: Headers,
    pub unsafe_request: bool,
    pub body: Option<Vec<u8>>,
    // TODO: client object
    pub type_: Type,
    pub destination: Destination,
    pub synchronous: bool,
    pub mode: RequestMode,
    pub cache_mode: CacheMode,
    pub use_cors_preflight: bool,
    pub credentials_mode: CredentialsMode,
    pub use_url_credentials: bool,
    // this should actually be set by fetch, but fetch
    // doesn't have info about the client right now
    pub origin: ServoUrl,
    // XXXManishearth these should be part of the client object
    pub referrer_url: Option<ServoUrl>,
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    pub redirect_mode: RedirectMode,
    pub integrity_metadata: String,
}

impl Default for RequestInit {
    fn default() -> RequestInit {
        RequestInit {
            method: Method::Get,
            url: ServoUrl::parse("about:blank").unwrap(),
            headers: Headers::new(),
            unsafe_request: false,
            body: None,
            type_: Type::None,
            destination: Destination::None,
            synchronous: false,
            mode: RequestMode::NoCors,
            cache_mode: CacheMode::Default,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            origin: ServoUrl::parse("about:blank").unwrap(),
            referrer_url: None,
            referrer_policy: None,
            pipeline_id: None,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: "".to_owned(),
        }
    }
}

/// A [Request](https://fetch.spec.whatwg.org/#requests) as defined by the Fetch spec
#[derive(Clone, HeapSizeOf)]
pub struct Request {
    #[ignore_heap_size_of = "Defined in hyper"]
    pub method: Method,
    pub local_urls_only: bool,
    pub sandboxed_storage_area_urls: bool,
    #[ignore_heap_size_of = "Defined in hyper"]
    pub headers: Headers,
    pub unsafe_request: bool,
    pub body: Option<Vec<u8>>,
    // TODO: client object
    pub is_service_worker_global_scope: bool,
    pub window: Window,
    // TODO: target browsing context
    pub keep_alive: bool,
    pub skip_service_worker: bool,
    pub initiator: Initiator,
    pub type_: Type,
    pub destination: Destination,
    // TODO: priority object
    pub origin: Origin,
    pub omit_origin_header: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-referrer
    pub referrer: Referrer,
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    pub synchronous: bool,
    pub mode: RequestMode,
    pub use_cors_preflight: bool,
    pub credentials_mode: CredentialsMode,
    pub use_url_credentials: bool,
    pub cache_mode: CacheMode,
    pub redirect_mode: RedirectMode,
    pub integrity_metadata: String,
    // Use the last method on url_list to act as spec current url field, and
    // first method to act as spec url field
    pub url_list: Vec<ServoUrl>,
    pub redirect_count: u32,
    pub response_tainting: ResponseTainting,
}

impl Request {
    pub fn new(url: ServoUrl,
               origin: Option<Origin>,
               is_service_worker_global_scope: bool,
               pipeline_id: Option<PipelineId>)
               -> Request {
        Request {
            method: Method::Get,
            local_urls_only: false,
            sandboxed_storage_area_urls: false,
            headers: Headers::new(),
            unsafe_request: false,
            body: None,
            is_service_worker_global_scope: is_service_worker_global_scope,
            window: Window::Client,
            keep_alive: false,
            skip_service_worker: false,
            initiator: Initiator::None,
            type_: Type::None,
            destination: Destination::None,
            origin: origin.unwrap_or(Origin::Client),
            omit_origin_header: false,
            referrer: Referrer::Client,
            referrer_policy: None,
            pipeline_id: pipeline_id,
            synchronous: false,
            mode: RequestMode::NoCors,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            cache_mode: CacheMode::Default,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: String::new(),
            url_list: vec![url],
            redirect_count: 0,
            response_tainting: ResponseTainting::Basic,
        }
    }

    pub fn from_init(init: RequestInit) -> Request {
        let mut req = Request::new(init.url,
                                   Some(Origin::Origin(init.origin.origin())),
                                   false,
                                   init.pipeline_id);
        req.method = init.method;
        req.headers = init.headers;
        req.unsafe_request = init.unsafe_request;
        req.body = init.body;
        req.type_ = init.type_;
        req.destination = init.destination;
        req.synchronous = init.synchronous;
        req.mode = init.mode;
        req.use_cors_preflight = init.use_cors_preflight;
        req.credentials_mode = init.credentials_mode;
        req.use_url_credentials = init.use_url_credentials;
        req.cache_mode = init.cache_mode;
        req.referrer = if let Some(url) = init.referrer_url {
            Referrer::ReferrerUrl(url)
        } else {
            Referrer::NoReferrer
        };
        req.referrer_policy = init.referrer_policy;
        req.pipeline_id = init.pipeline_id;
        req.redirect_mode = init.redirect_mode;
        req.integrity_metadata = init.integrity_metadata;
        req
    }

    pub fn url(&self) -> ServoUrl {
        self.url_list.first().unwrap().clone()
    }

    pub fn current_url(&self) -> ServoUrl {
        self.url_list.last().unwrap().clone()
    }

    pub fn is_navigation_request(&self) -> bool {
        self.destination == Destination::Document
    }

    pub fn is_subresource_request(&self) -> bool {
        match self.destination {
            Destination::Font | Destination::Image | Destination::Manifest | Destination::Media |
            Destination::Script | Destination::Style | Destination::XSLT | Destination::None => true,
            _ => false,
        }
    }
}

impl Referrer {
    pub fn to_url(&self) -> Option<&ServoUrl> {
        match *self {
            Referrer::NoReferrer | Referrer::Client => None,
            Referrer::ReferrerUrl(ref url) => Some(url),
        }
    }
}
<commit_msg>Add spec links to the Request fields<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use ReferrerPolicy;
use hyper::header::Headers;
use hyper::method::Method;
use msg::constellation_msg::PipelineId;
use servo_url::{ImmutableOrigin, ServoUrl};
use std::default::Default;

/// An [initiator](https://fetch.spec.whatwg.org/#concept-request-initiator)
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum Initiator {
    None,
    Download,
    ImageSet,
    Manifest,
    XSLT,
}

/// A request [type](https://fetch.spec.whatwg.org/#concept-request-type)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum Type {
    None,
    Audio,
    Font,
    Image,
    Script,
    Style,
    Track,
    Video,
}

/// A request [destination](https://fetch.spec.whatwg.org/#concept-request-destination)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum Destination {
    None,
    Document,
    Embed,
    Font,
    Image,
    Manifest,
    Media,
    Object,
    Report,
    Script,
    ServiceWorker,
    SharedWorker,
    Style,
    Worker,
    XSLT,
}

/// A request [origin](https://fetch.spec.whatwg.org/#concept-request-origin)
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, HeapSizeOf)]
pub enum Origin {
    Client,
    Origin(ImmutableOrigin),
}

/// A [referer](https://fetch.spec.whatwg.org/#concept-request-referrer)
#[derive(Clone, PartialEq, HeapSizeOf)]
pub enum Referrer {
    NoReferrer,
    /// Default referrer if nothing is specified
    Client,
    ReferrerUrl(ServoUrl),
}

/// A [request mode](https://fetch.spec.whatwg.org/#concept-request-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum RequestMode {
    Navigate,
    SameOrigin,
    NoCors,
    CorsMode,
    WebSocket
}

/// Request [credentials mode](https://fetch.spec.whatwg.org/#concept-request-credentials-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum CredentialsMode {
    Omit,
    CredentialsSameOrigin,
    Include,
}

/// [Cache mode](https://fetch.spec.whatwg.org/#concept-request-cache-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum CacheMode {
    Default,
    NoStore,
    Reload,
    NoCache,
    ForceCache,
    OnlyIfCached,
}

/// [Redirect mode](https://fetch.spec.whatwg.org/#concept-request-redirect-mode)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize, HeapSizeOf)]
pub enum RedirectMode {
    Follow,
    Error,
    Manual,
}

/// [Response tainting](https://fetch.spec.whatwg.org/#concept-request-response-tainting)
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum ResponseTainting {
    Basic,
    CorsTainting,
    Opaque,
}

/// [Window](https://fetch.spec.whatwg.org/#concept-request-window)
#[derive(Copy, Clone, PartialEq, HeapSizeOf)]
pub enum Window {
    NoWindow,
    Client, // TODO: Environmental settings object
}

/// [CORS settings attribute](https://html.spec.whatwg.org/multipage/#attr-crossorigin-anonymous)
#[derive(Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum CorsSettings {
    Anonymous,
    UseCredentials,
}

#[derive(Serialize, Deserialize, Clone, HeapSizeOf)]
pub struct RequestInit {
    #[serde(deserialize_with = "::hyper_serde::deserialize",
            serialize_with = "::hyper_serde::serialize")]
    #[ignore_heap_size_of = "Defined in hyper"]
    pub method: Method,
    pub url: ServoUrl,
    #[serde(deserialize_with = "::hyper_serde::deserialize",
            serialize_with = "::hyper_serde::serialize")]
    #[ignore_heap_size_of = "Defined in hyper"]
    pub headers: Headers,
    pub unsafe_request: bool,
    pub body: Option<Vec<u8>>,
    // TODO: client object
    pub type_: Type,
    pub destination: Destination,
    pub synchronous: bool,
    pub mode: RequestMode,
    pub cache_mode: CacheMode,
    pub use_cors_preflight: bool,
    pub credentials_mode: CredentialsMode,
    pub use_url_credentials: bool,
    // this should actually be set by fetch, but fetch
    // doesn't have info about the client right now
    pub origin: ServoUrl,
    // XXXManishearth these should be part of the client object
    pub referrer_url: Option<ServoUrl>,
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    pub redirect_mode: RedirectMode,
    pub integrity_metadata: String,
}

impl Default for RequestInit {
    fn default() -> RequestInit {
        RequestInit {
            method: Method::Get,
            url: ServoUrl::parse("about:blank").unwrap(),
            headers: Headers::new(),
            unsafe_request: false,
            body: None,
            type_: Type::None,
            destination: Destination::None,
            synchronous: false,
            mode: RequestMode::NoCors,
            cache_mode: CacheMode::Default,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            origin: ServoUrl::parse("about:blank").unwrap(),
            referrer_url: None,
            referrer_policy: None,
            pipeline_id: None,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: "".to_owned(),
        }
    }
}

/// A [Request](https://fetch.spec.whatwg.org/#concept-request) as defined by
/// the Fetch spec.
#[derive(Clone, HeapSizeOf)]
pub struct Request {
    /// https://fetch.spec.whatwg.org/#concept-request-method
    #[ignore_heap_size_of = "Defined in hyper"]
    pub method: Method,
    /// https://fetch.spec.whatwg.org/#local-urls-only-flag
    pub local_urls_only: bool,
    /// https://fetch.spec.whatwg.org/#sandboxed-storage-area-urls-flag
    pub sandboxed_storage_area_urls: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-header-list
    #[ignore_heap_size_of = "Defined in hyper"]
    pub headers: Headers,
    /// https://fetch.spec.whatwg.org/#unsafe-request-flag
    pub unsafe_request: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-body
    pub body: Option<Vec<u8>>,
    // TODO: client object
    pub is_service_worker_global_scope: bool,
    pub window: Window,
    // TODO: target browsing context
    /// https://fetch.spec.whatwg.org/#request-keepalive-flag
    pub keep_alive: bool,
    pub skip_service_worker: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-initiator
    pub initiator: Initiator,
    /// https://fetch.spec.whatwg.org/#concept-request-type
    pub type_: Type,
    /// https://fetch.spec.whatwg.org/#concept-request-destination
    pub destination: Destination,
    // TODO: priority object
    /// https://fetch.spec.whatwg.org/#concept-request-origin
    pub origin: Origin,
    pub omit_origin_header: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-referrer
    pub referrer: Referrer,
    /// https://fetch.spec.whatwg.org/#concept-request-referrer-policy
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    /// https://fetch.spec.whatwg.org/#synchronous-flag
    pub synchronous: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-mode
    pub mode: RequestMode,
    /// https://fetch.spec.whatwg.org/#use-cors-preflight-flag
    pub use_cors_preflight: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-credentials-mode
    pub credentials_mode: CredentialsMode,
    /// https://fetch.spec.whatwg.org/#concept-request-use-url-credentials-flag
    pub use_url_credentials: bool,
    /// https://fetch.spec.whatwg.org/#concept-request-cache-mode
    pub cache_mode: CacheMode,
    /// https://fetch.spec.whatwg.org/#concept-request-redirect-mode
    pub redirect_mode: RedirectMode,
    /// https://fetch.spec.whatwg.org/#concept-request-integrity-metadata
    pub integrity_metadata: String,
    // Use the last method on url_list to act as spec current url field, and
    // first method to act as spec url field
    /// https://fetch.spec.whatwg.org/#concept-request-url-list
    pub url_list: Vec<ServoUrl>,
    /// https://fetch.spec.whatwg.org/#concept-request-redirect-count
    pub redirect_count: u32,
    /// https://fetch.spec.whatwg.org/#concept-request-response-tainting
    pub response_tainting: ResponseTainting,
}

impl Request {
    pub fn new(url: ServoUrl,
               origin: Option<Origin>,
               is_service_worker_global_scope: bool,
               pipeline_id: Option<PipelineId>)
               -> Request {
        Request {
            method: Method::Get,
            local_urls_only: false,
            sandboxed_storage_area_urls: false,
            headers: Headers::new(),
            unsafe_request: false,
            body: None,
            is_service_worker_global_scope: is_service_worker_global_scope,
            window: Window::Client,
            keep_alive: false,
            skip_service_worker: false,
            initiator: Initiator::None,
            type_: Type::None,
            destination: Destination::None,
            origin: origin.unwrap_or(Origin::Client),
            omit_origin_header: false,
            referrer: Referrer::Client,
            referrer_policy: None,
            pipeline_id: pipeline_id,
            synchronous: false,
            mode: RequestMode::NoCors,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            cache_mode: CacheMode::Default,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: String::new(),
            url_list: vec![url],
            redirect_count: 0,
            response_tainting: ResponseTainting::Basic,
        }
    }

    pub fn from_init(init: RequestInit) -> Request {
        let mut req = Request::new(init.url,
                                   Some(Origin::Origin(init.origin.origin())),
                                   false,
                                   init.pipeline_id);
        req.method = init.method;
        req.headers = init.headers;
        req.unsafe_request = init.unsafe_request;
        req.body = init.body;
        req.type_ = init.type_;
        req.destination = init.destination;
        req.synchronous = init.synchronous;
        req.mode = init.mode;
        req.use_cors_preflight = init.use_cors_preflight;
        req.credentials_mode = init.credentials_mode;
        req.use_url_credentials = init.use_url_credentials;
        req.cache_mode = init.cache_mode;
        req.referrer = if let Some(url) = init.referrer_url {
            Referrer::ReferrerUrl(url)
        } else {
            Referrer::NoReferrer
        };
        req.referrer_policy = init.referrer_policy;
        req.pipeline_id = init.pipeline_id;
        req.redirect_mode = init.redirect_mode;
        req.integrity_metadata = init.integrity_metadata;
        req
    }

    /// https://fetch.spec.whatwg.org/#concept-request-url
    pub fn url(&self) -> ServoUrl {
        self.url_list.first().unwrap().clone()
    }

    /// https://fetch.spec.whatwg.org/#concept-request-current-url
    pub fn current_url(&self) -> ServoUrl {
        self.url_list.last().unwrap().clone()
    }

    /// https://fetch.spec.whatwg.org/#navigation-request
    pub fn is_navigation_request(&self) -> bool {
        self.destination == Destination::Document
    }

    /// https://fetch.spec.whatwg.org/#subresource-request
    pub fn is_subresource_request(&self) -> bool {
        match self.destination {
            Destination::Font | Destination::Image | Destination::Manifest | Destination::Media |
            Destination::Script | Destination::Style | Destination::XSLT | Destination::None => true,
            _ => false,
        }
    }
}

impl Referrer {
    pub fn to_url(&self) -> Option<&ServoUrl> {
        match *self {
            Referrer::NoReferrer | Referrer::Client => None,
            Referrer::ReferrerUrl(ref url) => Some(url),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Matthew O'Connor
extern crate system_zero_core;

use std::io;
use std::io::{BufRead, Write};
use system_zero_core::*;
use system_zero_core::ast::*;

const BOOL: &'static str = include_str!("bool.sz");
const NAT: &'static str = include_str!("nat.sz");
const LIST: &'static str = include_str!("list.sz");

fn load_prelude(env: &mut Env) {
  env.load(BOOL);
  env.load(NAT);
  env.load(LIST);
}

const PROMPT: &'static str = "> ";

fn prompt() -> () {
  print!("{}", PROMPT);
  io::stdout().flush().unwrap()
}

fn repl() -> io::Result<()> {
  let mut history: Vec<String> = vec![];
  let mut env = Env::new();
  load_prelude(&mut env);
  prompt();
  let stdin = io::stdin();
  for line in stdin.lock().lines() {
    let line = line.unwrap();
    if line == ":env" {
      print!("{:?}", env);
    } else if line == ":history" {
      println!("{:?}", history);
    } else if line == ":quit" || line == ":exit" {
      break;
    } else if line == ":clear" {
      env.clear();
      load_prelude(&mut env);
    } else if line.starts_with("--") {
      ()
    } else if line.len() > 0 {
      history.push(line.clone());
      match parse_one(&line[..]) {
        Ok(one) => {
          match one {
            One::Def(ref def) => {
              let def = def.normalize_in(&mut env);
              let one = One::Def(def.clone());
              print!("{:?}", one);
              env.push(def);
            }
            One::Expr(ref e) => {
              print!("{:?}", One::Expr(e.normalize_in(&mut env)))
            }
          }
        }
        Err(error) => println!("Couldn't parse: {:?}", error),
      }
    }
    prompt();
  }
  Ok(())
}

fn main() {
  println!("szi - system zero interpreter");
  println!("Copyright (c) 2016, Matthew O'Connor <thegreendragon@gmail.com>");
  // Return 0 if repl returned Ok.
  std::process::exit(!repl().is_ok() as i32)
}
<commit_msg>Split REPL into multiple functions - one for eval and one for REPL commands.<commit_after>// Copyright (c) 2016, Matthew O'Connor
extern crate system_zero_core;

use std::io;
use std::io::{BufRead, Write};
use system_zero_core::*;
use system_zero_core::ast::*;

const BOOL: &'static str = include_str!("bool.sz");
const NAT: &'static str = include_str!("nat.sz");
const LIST: &'static str = include_str!("list.sz");

fn load_prelude(env: &mut Env) {
  env.load(BOOL);
  env.load(NAT);
  env.load(LIST);
}

const PROMPT: &'static str = "> ";

fn prompt() -> () {
  print!("{}", PROMPT);
  io::stdout().flush().unwrap()
}

fn support(line: &String, mut env: &mut Env, history: &Vec<String>) {
  if line == ":env" {
    print!("{:?}", env);
  } else if line == ":history" {
    println!("{:?}", history);
  } else if line == ":quit" || line == ":exit" {
    std::process::exit(1);
  } else if line == ":clear" {
    env.clear();
    load_prelude(&mut env);
  } else if line.starts_with(":ty ") {
    let name = &line[4..];
    match env.get_ty(&Var::new(name, 0)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No type for `{}`", name),
    }
  } else if line.starts_with(":val ") {
    let name = &line[5..];
    match env.get_val(&Var::new(name, 0)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No value for `{}`", name),
    }
  } else if line.starts_with(":def ") {
    let name = &line[5..];
    match env.get_ty(&Var::new(name, 0)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No type for `{}`", name),
    }
    match env.get_val(&Var::new(name, 0)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No value for `{}`", name),
    }
  }
}

fn eval<'input>(line: &'input str, mut env: &mut Env) -> Result<'input, One> {
  match parse_one(&line) {
    Ok(one) => {
      match one {
        One::Def(ref def) => {
          let def = def.normalize_in(&mut env);
          let one = One::Def(def.clone());
          env.push(def);
          Ok(one)
        }
        One::Expr(ref e) => Ok(One::Expr(e.normalize_in(&mut env))),
      }
    }
    Err(error) => Err(error),
  }
}

fn repl() -> io::Result<()> {
  let mut history: Vec<String> = vec![];
  let mut env = Env::new();
  load_prelude(&mut env);
  prompt();
  let stdin = io::stdin();
  for line in stdin.lock().lines() {
    let line = line.unwrap();
    history.push(line.clone());
    if line.starts_with("--") {
      ()
    } else if line.starts_with(":") {
      support(&line, &mut env, &history);
    } else if line.len() > 0 {
      match eval(&line[..], &mut env) {
        Ok(one) => print!("{:?}", one),
        Err(error) => println!("Couldn't parse: {:?}", error),
      }
    }
    prompt();
  }
  Ok(())
}

fn main() {
  println!("szi - system zero interpreter");
  println!("Copyright (c) 2016, Matthew O'Connor <thegreendragon@gmail.com>");
  repl().unwrap()
}
<|endoftext|>


<commit_before>//! The CXX code generator for constructing and compiling C++ code.
//!
//! This is intended to be used from Cargo build scripts to execute CXX's
//! C++ code generator, set up any additional compiler flags depending on
//! the use case, and make the C++ compiler invocation.
//!
//!

//!
//! # Example
//!
//! Example of a canonical Cargo build script that builds a CXX bridge:
//!
//! ```no_run
//! // build.rs
//!
//! fn main() {
//!     cxx_build::bridge("src/main.rs")
//!         .file("../demo-cxx/demo.cc")
//!         .flag_if_supported("-std=c++11")
//!         .compile("cxxbridge-demo");
//!
//!     println!("cargo:rerun-if-changed=src/main.rs");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.h");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.cc");
//! }
//! ```
//!
//! A runnable working setup with this build script is shown in the
//! *demo-rs* and *demo-cxx* directories of [https://github.com/dtolnay/cxx].
//!
//! [https://github.com/dtolnay/cxx]: https://github.com/dtolnay/cxx
//!
//!

//!
//! # Alternatives
//!
//! For use in non-Cargo builds like Bazel or Buck, CXX provides an
//! alternate way of invoking the C++ code generator as a standalone command
//! line tool. The tool is packaged as the `cxxbridge-cmd` crate.
//!
//! ```bash
//! $ cargo install cxxbridge-cmd  # or build it from the repo
//!
//! $ cxxbridge src/main.rs --header > path/to/mybridge.h
//! $ cxxbridge src/main.rs > path/to/mybridge.cc
//! ```

#![allow(
    clippy::inherent_to_string,
    clippy::needless_doctest_main,
    clippy::new_without_default,
    clippy::toplevel_ref_arg
)]

mod error;
mod gen;
mod paths;
mod syntax;

use crate::error::Result;
use crate::gen::error::report;
use crate::gen::{fs, Opt};
use std::io::{self, Write};
use std::iter;
use std::path::Path;
use std::process;

/// This returns a [`cc::Build`] on which you should continue to set up any
/// additional source files or compiler flags, and lastly call its [`compile`]
/// method to execute the C++ build.
///
/// [`compile`]: https://docs.rs/cc/1.0.49/cc/struct.Build.html#method.compile
#[must_use]
pub fn bridge(rust_source_file: impl AsRef<Path>) -> cc::Build {
    bridges(iter::once(rust_source_file))
}

/// `cxx_build::bridge` but for when more than one file contains a
/// #\[cxx::bridge\] module.
///
/// ```no_run
/// let source_files = vec!["src/main.rs", "src/path/to/other.rs"];
/// cxx_build::bridges(source_files)
///     .file("../demo-cxx/demo.cc")
///     .flag_if_supported("-std=c++11")
///     .compile("cxxbridge-demo");
/// ```
pub fn bridges(rust_source_files: impl IntoIterator<Item = impl AsRef<Path>>) -> cc::Build {
    let mut build = paths::cc_build();
    build.cpp(true);
    build.cpp_link_stdlib(None); // linked via link-cplusplus crate

    for path in rust_source_files {
        if let Err(err) = try_generate_bridge(&mut build, path.as_ref()) {
            let _ = writeln!(io::stderr(), "\n\ncxxbridge error: {}\n\n", report(err));
            process::exit(1);
        }
    }

    build
}

fn try_generate_bridge(build: &mut cc::Build, rust_source_file: &Path) -> Result<()> {
    let opt = Opt::default();
    let generated = gen::generate_from_path(rust_source_file, &opt);

    let header_path = paths::out_with_extension(rust_source_file, ".h")?;
    fs::create_dir_all(header_path.parent().unwrap())?;
    fs::write(&header_path, generated.header)?;
    paths::symlink_header(&header_path, rust_source_file);

    let implementation_path = paths::out_with_extension(rust_source_file, ".cc")?;
    fs::write(&implementation_path, generated.implementation)?;
    build.file(&implementation_path);

    let ref cxx_h = paths::include_dir()?.join("rust").join("cxx.h");
    let _ = fs::create_dir_all(cxx_h.parent().unwrap());
    let _ = fs::remove_file(cxx_h);
    let _ = fs::write(cxx_h, gen::include::HEADER);

    Ok(())
}
<commit_msg>Import cc::Build<commit_after>//! The CXX code generator for constructing and compiling C++ code.
//!
//! This is intended to be used from Cargo build scripts to execute CXX's
//! C++ code generator, set up any additional compiler flags depending on
//! the use case, and make the C++ compiler invocation.
//!
//!

//!
//! # Example
//!
//! Example of a canonical Cargo build script that builds a CXX bridge:
//!
//! ```no_run
//! // build.rs
//!
//! fn main() {
//!     cxx_build::bridge("src/main.rs")
//!         .file("../demo-cxx/demo.cc")
//!         .flag_if_supported("-std=c++11")
//!         .compile("cxxbridge-demo");
//!
//!     println!("cargo:rerun-if-changed=src/main.rs");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.h");
//!     println!("cargo:rerun-if-changed=../demo-cxx/demo.cc");
//! }
//! ```
//!
//! A runnable working setup with this build script is shown in the
//! *demo-rs* and *demo-cxx* directories of [https://github.com/dtolnay/cxx].
//!
//! [https://github.com/dtolnay/cxx]: https://github.com/dtolnay/cxx
//!
//!

//!
//! # Alternatives
//!
//! For use in non-Cargo builds like Bazel or Buck, CXX provides an
//! alternate way of invoking the C++ code generator as a standalone command
//! line tool. The tool is packaged as the `cxxbridge-cmd` crate.
//!
//! ```bash
//! $ cargo install cxxbridge-cmd  # or build it from the repo
//!
//! $ cxxbridge src/main.rs --header > path/to/mybridge.h
//! $ cxxbridge src/main.rs > path/to/mybridge.cc
//! ```

#![allow(
    clippy::inherent_to_string,
    clippy::needless_doctest_main,
    clippy::new_without_default,
    clippy::toplevel_ref_arg
)]

mod error;
mod gen;
mod paths;
mod syntax;

use crate::error::Result;
use crate::gen::error::report;
use crate::gen::{fs, Opt};
use cc::Build;
use std::io::{self, Write};
use std::iter;
use std::path::Path;
use std::process;

/// This returns a [`cc::Build`] on which you should continue to set up any
/// additional source files or compiler flags, and lastly call its [`compile`]
/// method to execute the C++ build.
///
/// [`compile`]: https://docs.rs/cc/1.0.49/cc/struct.Build.html#method.compile
#[must_use]
pub fn bridge(rust_source_file: impl AsRef<Path>) -> Build {
    bridges(iter::once(rust_source_file))
}

/// `cxx_build::bridge` but for when more than one file contains a
/// #\[cxx::bridge\] module.
///
/// ```no_run
/// let source_files = vec!["src/main.rs", "src/path/to/other.rs"];
/// cxx_build::bridges(source_files)
///     .file("../demo-cxx/demo.cc")
///     .flag_if_supported("-std=c++11")
///     .compile("cxxbridge-demo");
/// ```
pub fn bridges(rust_source_files: impl IntoIterator<Item = impl AsRef<Path>>) -> Build {
    let mut build = paths::cc_build();
    build.cpp(true);
    build.cpp_link_stdlib(None); // linked via link-cplusplus crate

    for path in rust_source_files {
        if let Err(err) = try_generate_bridge(&mut build, path.as_ref()) {
            let _ = writeln!(io::stderr(), "\n\ncxxbridge error: {}\n\n", report(err));
            process::exit(1);
        }
    }

    build
}

fn try_generate_bridge(build: &mut Build, rust_source_file: &Path) -> Result<()> {
    let opt = Opt::default();
    let generated = gen::generate_from_path(rust_source_file, &opt);

    let header_path = paths::out_with_extension(rust_source_file, ".h")?;
    fs::create_dir_all(header_path.parent().unwrap())?;
    fs::write(&header_path, generated.header)?;
    paths::symlink_header(&header_path, rust_source_file);

    let implementation_path = paths::out_with_extension(rust_source_file, ".cc")?;
    fs::write(&implementation_path, generated.implementation)?;
    build.file(&implementation_path);

    let ref cxx_h = paths::include_dir()?.join("rust").join("cxx.h");
    let _ = fs::create_dir_all(cxx_h.parent().unwrap());
    let _ = fs::remove_file(cxx_h);
    let _ = fs::write(cxx_h, gen::include::HEADER);

    Ok(())
}
<|endoftext|>


<commit_before>//! Module for built-in filter functions
//!
//! Contains all the built-in filter functions for use in templates.
//! You can define your own filters; for more information,
//! see the top-level crate documentation.

#[cfg(feature = "serde-json")]
mod json;

#[cfg(feature = "serde-json")]
pub use self::json::json;

use num_traits::Signed;
use std::fmt;

use super::Result;
use escaping::{self, MarkupDisplay};

// This is used by the code generator to decide whether a named filter is part of
// Askama or should refer to a local `filters` module. It should contain all the
// filters shipped with Askama, even the optional ones (since optional inclusion
// in the const vector based on features seems impossible right now).
pub const BUILT_IN_FILTERS: [&str; 18] = [
    "abs",
    "capitalize",
    "center",
    "e",
    "escape",
    "format",
    "join",
    "linebreaks",
    "linebreaksbr",
    "lower",
    "lowercase",
    "safe",
    "trim",
    "truncate",
    "upper",
    "uppercase",
    "wordcount",
    "json", // Optional feature; reserve the name anyway
];

/// Marks a string (or other `Display` type) as safe
///
/// Use this is you want to allow markup in an expression, or if you know
/// that the expression's contents don't need to be escaped.
pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From,
{
    let res: MarkupDisplay<D> = v.into();
    Ok(res.mark_safe())
}

/// Escapes `&`, `<` and `>` in strings
pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From,
{
    let md: MarkupDisplay<D> = i.into();
    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
}

/// Alias for the `escape()` filter
pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From,
{
    escape(i)
}

/// Formats arguments according to the specified format
///
/// The first argument to this filter must be a string literal (as in normal
/// Rust). All arguments are passed through to the `format!()`
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
/// the Askama code generator.
pub fn format() {}

/// Replaces line breaks in plain text with appropriate HTML
///
/// A single newline becomes an HTML line break `<br>` and a new line
/// followed by a blank line becomes a paragraph break `<p>`.
pub fn linebreaks(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    let linebroken = s.replace("\n\n", "

").replace("\n", "
");

    Ok(format!("
{}
", linebroken))
}

/// Converts all newlines in a piece of plain text to HTML line breaks
pub fn linebreaksbr(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.replace("\n", "
"))
}

/// Converts to lowercase
pub fn lower(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_lowercase())
}

/// Alias for the `lower()` filter
pub fn lowercase(s: &fmt::Display) -> Result<String> {
    lower(s)
}

/// Converts to uppercase
pub fn upper(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_uppercase())
}

/// Alias for the `upper()` filter
pub fn uppercase(s: &fmt::Display) -> Result<String> {
    upper(s)
}

/// Strip leading and trailing whitespace
pub fn trim(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.trim().to_owned())
}

/// Limit string length, appends '...' if truncated
pub fn truncate(s: &fmt::Display, len: &usize) -> Result<String> {
    let mut s = format!("{}", s);
    if s.len() < *len {
        Ok(s)
    } else {
        s.truncate(*len);
        s.push_str("...");
        Ok(s)
    }
}

/// Joins iterable into a string separated by provided argument
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
where
    T: fmt::Display,
    I: Iterator<Item = T>,
    S: AsRef<str>,
{
    let separator: &str = separator.as_ref();

    let mut rv = String::new();

    for (num, item) in input.enumerate() {
        if num > 0 {
            rv.push_str(separator);
        }

        rv.push_str(&format!("{}", item));
    }

    Ok(rv)
}

/// Absolute value
pub fn abs<T>(number: T) -> Result<T>
where
    T: Signed,
{
    Ok(number.abs())
}

/// Capitalize a value. The first character will be uppercase, all others lowercase.
pub fn capitalize(s: &fmt::Display) -> Result<String> {
    let mut s = format!("{}", s);

    match s.get_mut(0..1).map(|s| {
        s.make_ascii_uppercase();
        &*s
    }) {
        None => Ok(s),
        _ => {
            let l = s.len();
            match s.get_mut(1..l).map(|s| {
                s.make_ascii_lowercase();
                &*s
            }) {
                _ => Ok(s),
            }
        }
    }
}

/// Centers the value in a field of a given width.
pub fn center(s: &fmt::Display, l: usize) -> Result<String> {
    let s = format!("{}", s);
    let len = s.len();

    if l <= len {
        Ok(s)
    } else {
        let p = l - len;
        let q = p / 2;
        let r = p % 2;
        let mut buf = String::with_capacity(l);

        for _ in 0..q {
            buf.push(' ');
        }

        buf.push_str(&s);

        for _ in 0..q + r {
            buf.push(' ');
        }

        Ok(buf)
    }
}

/// Count the words in that string.
pub fn wordcount(s: &fmt::Display) -> Result<usize> {
    let s = format!("{}", s);

    Ok(s.split_whitespace().count())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_linebreaks() {
        assert_eq!(
            linebreaks(&"Foo\nBar Baz").unwrap(),
            "
Foo
Bar Baz
"
        );
        assert_eq!(
            linebreaks(&"Foo\nBar\n\nBaz").unwrap(),
            "
Foo
Bar

Baz
"
        );
    }

    #[test]
    fn test_linebreaksbr() {
        assert_eq!(linebreaksbr(&"Foo\nBar").unwrap(), "Foo
Bar");
        assert_eq!(
            linebreaksbr(&"Foo\nBar\n\nBaz").unwrap(),
            "Foo
Bar

Baz"
        );
    }

    #[test]
    fn test_lower() {
        assert_eq!(lower(&"Foo").unwrap(), "foo");
        assert_eq!(lower(&"FOO").unwrap(), "foo");
        assert_eq!(lower(&"FooBar").unwrap(), "foobar");
        assert_eq!(lower(&"foo").unwrap(), "foo");
    }

    #[test]
    fn test_upper() {
        assert_eq!(upper(&"Foo").unwrap(), "FOO");
        assert_eq!(upper(&"FOO").unwrap(), "FOO");
        assert_eq!(upper(&"FooBar").unwrap(), "FOOBAR");
        assert_eq!(upper(&"foo").unwrap(), "FOO");
    }

    #[test]
    fn test_trim() {
        assert_eq!(trim(&" Hello\tworld\t").unwrap(), "Hello\tworld");
    }

    #[test]
    fn test_join() {
        assert_eq!(
            join((&["hello", "world"]).into_iter(), ", ").unwrap(),
            "hello, world"
        );
        assert_eq!(join((&["hello"]).into_iter(), ", ").unwrap(), "hello");

        let empty: &[&str] = &[];
        assert_eq!(join(empty.into_iter(), ", ").unwrap(), "");

        let input: Vec<String> = vec!["foo".into(), "bar".into(), "bazz".into()];
        assert_eq!(
            join((&input).into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":").unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );

        let input: &[String] = &["foo".into(), "bar".into()];
        assert_eq!(join(input.into_iter(), ":").unwrap(), "foo:bar");
        assert_eq!(join(input.into_iter(), ":".to_string()).unwrap(), "foo:bar");

        let real: String = "blah".into();
        let input: Vec<&str> = vec![&real];
        assert_eq!(join(input.into_iter(), ";").unwrap(), "blah");

        assert_eq!(
            join((&&&&&["foo", "bar"]).into_iter(), ", ").unwrap(),
            "foo, bar"
        );
    }

    #[test]
    fn test_abs() {
        assert_eq!(abs(1).unwrap(), 1);
        assert_eq!(abs(-1).unwrap(), 1);
        assert_eq!(abs(1.0).unwrap(), 1.0);
        assert_eq!(abs(-1.0).unwrap(), 1.0);
        assert_eq!(abs(1.0 as f64).unwrap(), 1.0 as f64);
        assert_eq!(abs(-1.0 as f64).unwrap(), 1.0 as f64);
    }

    #[test]
    fn test_capitalize() {
        assert_eq!(capitalize(&"foo").unwrap(), "Foo".to_string());
        assert_eq!(capitalize(&"f").unwrap(), "F".to_string());
        assert_eq!(capitalize(&"fO").unwrap(), "Fo".to_string());
        assert_eq!(capitalize(&"").unwrap(), "".to_string());
        assert_eq!(capitalize(&"FoO").unwrap(), "Foo".to_string());
        assert_eq!(capitalize(&"foO BAR").unwrap(), "Foo bar".to_string());
    }

    #[test]
    fn test_center() {
        assert_eq!(center(&"f", 3).unwrap(), " f ".to_string());
        assert_eq!(center(&"f", 4).unwrap(), " f  ".to_string());
        assert_eq!(center(&"foo", 1).unwrap(), "foo".to_string());
        assert_eq!(center(&"foo bar", 8).unwrap(), "foo bar ".to_string());
    }

    #[test]
    fn test_wordcount() {
        assert_eq!(wordcount(&"").unwrap(), 0);
        assert_eq!(wordcount(&" \n\t").unwrap(), 0);
        assert_eq!(wordcount(&"foo").unwrap(), 1);
        assert_eq!(wordcount(&"foo bar").unwrap(), 2);
    }
}
<commit_msg>Remove periods from documentation sentence fragments<commit_after>//! Module for built-in filter functions
//!
//! Contains all the built-in filter functions for use in templates.
//! You can define your own filters; for more information,
//! see the top-level crate documentation.

#[cfg(feature = "serde-json")]
mod json;

#[cfg(feature = "serde-json")]
pub use self::json::json;

use num_traits::Signed;
use std::fmt;

use super::Result;
use escaping::{self, MarkupDisplay};

// This is used by the code generator to decide whether a named filter is part of
// Askama or should refer to a local `filters` module. It should contain all the
// filters shipped with Askama, even the optional ones (since optional inclusion
// in the const vector based on features seems impossible right now).
pub const BUILT_IN_FILTERS: [&str; 18] = [
    "abs",
    "capitalize",
    "center",
    "e",
    "escape",
    "format",
    "join",
    "linebreaks",
    "linebreaksbr",
    "lower",
    "lowercase",
    "safe",
    "trim",
    "truncate",
    "upper",
    "uppercase",
    "wordcount",
    "json", // Optional feature; reserve the name anyway
];

/// Marks a string (or other `Display` type) as safe
///
/// Use this is you want to allow markup in an expression, or if you know
/// that the expression's contents don't need to be escaped.
pub fn safe<D, I>(v: I) -> Result<MarkupDisplay<D>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From,
{
    let res: MarkupDisplay<D> = v.into();
    Ok(res.mark_safe())
}

/// Escapes `&`, `<` and `>` in strings
pub fn escape<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From,
{
    let md: MarkupDisplay<D> = i.into();
    Ok(MarkupDisplay::Safe(escaping::escape(md.unsafe_string())))
}

/// Alias for the `escape()` filter
pub fn e<D, I>(i: I) -> Result<MarkupDisplay<String>>
where
    D: fmt::Display,
    MarkupDisplay<D>: From,
{
    escape(i)
}

/// Formats arguments according to the specified format
///
/// The first argument to this filter must be a string literal (as in normal
/// Rust). All arguments are passed through to the `format!()`
/// [macro](https://doc.rust-lang.org/stable/std/macro.format.html) by
/// the Askama code generator.
pub fn format() {}

/// Replaces line breaks in plain text with appropriate HTML
///
/// A single newline becomes an HTML line break `<br>` and a new line
/// followed by a blank line becomes a paragraph break `<p>`.
pub fn linebreaks(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    let linebroken = s.replace("\n\n", "

").replace("\n", "
");

    Ok(format!("
{}
", linebroken))
}

/// Converts all newlines in a piece of plain text to HTML line breaks
pub fn linebreaksbr(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.replace("\n", "
"))
}

/// Converts to lowercase
pub fn lower(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_lowercase())
}

/// Alias for the `lower()` filter
pub fn lowercase(s: &fmt::Display) -> Result<String> {
    lower(s)
}

/// Converts to uppercase
pub fn upper(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.to_uppercase())
}

/// Alias for the `upper()` filter
pub fn uppercase(s: &fmt::Display) -> Result<String> {
    upper(s)
}

/// Strip leading and trailing whitespace
pub fn trim(s: &fmt::Display) -> Result<String> {
    let s = format!("{}", s);
    Ok(s.trim().to_owned())
}

/// Limit string length, appends '...' if truncated
pub fn truncate(s: &fmt::Display, len: &usize) -> Result<String> {
    let mut s = format!("{}", s);
    if s.len() < *len {
        Ok(s)
    } else {
        s.truncate(*len);
        s.push_str("...");
        Ok(s)
    }
}

/// Joins iterable into a string separated by provided argument
pub fn join<T, I, S>(input: I, separator: S) -> Result<String>
where
    T: fmt::Display,
    I: Iterator<Item = T>,
    S: AsRef<str>,
{
    let separator: &str = separator.as_ref();

    let mut rv = String::new();

    for (num, item) in input.enumerate() {
        if num > 0 {
            rv.push_str(separator);
        }

        rv.push_str(&format!("{}", item));
    }

    Ok(rv)
}

/// Absolute value
pub fn abs<T>(number: T) -> Result<T>
where
    T: Signed,
{
    Ok(number.abs())
}

/// Capitalize a value. The first character will be uppercase, all others lowercase.
pub fn capitalize(s: &fmt::Display) -> Result<String> {
    let mut s = format!("{}", s);

    match s.get_mut(0..1).map(|s| {
        s.make_ascii_uppercase();
        &*s
    }) {
        None => Ok(s),
        _ => {
            let l = s.len();
            match s.get_mut(1..l).map(|s| {
                s.make_ascii_lowercase();
                &*s
            }) {
                _ => Ok(s),
            }
        }
    }
}

/// Centers the value in a field of a given width
pub fn center(s: &fmt::Display, l: usize) -> Result<String> {
    let s = format!("{}", s);
    let len = s.len();

    if l <= len {
        Ok(s)
    } else {
        let p = l - len;
        let q = p / 2;
        let r = p % 2;
        let mut buf = String::with_capacity(l);

        for _ in 0..q {
            buf.push(' ');
        }

        buf.push_str(&s);

        for _ in 0..q + r {
            buf.push(' ');
        }

        Ok(buf)
    }
}

/// Count the words in that string
pub fn wordcount(s: &fmt::Display) -> Result<usize> {
    let s = format!("{}", s);

    Ok(s.split_whitespace().count())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_linebreaks() {
        assert_eq!(
            linebreaks(&"Foo\nBar Baz").unwrap(),
            "
Foo
Bar Baz
"
        );
        assert_eq!(
            linebreaks(&"Foo\nBar\n\nBaz").unwrap(),
            "
Foo
Bar

Baz
"
        );
    }

    #[test]
    fn test_linebreaksbr() {
        assert_eq!(linebreaksbr(&"Foo\nBar").unwrap(), "Foo
Bar");
        assert_eq!(
            linebreaksbr(&"Foo\nBar\n\nBaz").unwrap(),
            "Foo
Bar

Baz"
        );
    }

    #[test]
    fn test_lower() {
        assert_eq!(lower(&"Foo").unwrap(), "foo");
        assert_eq!(lower(&"FOO").unwrap(), "foo");
        assert_eq!(lower(&"FooBar").unwrap(), "foobar");
        assert_eq!(lower(&"foo").unwrap(), "foo");
    }

    #[test]
    fn test_upper() {
        assert_eq!(upper(&"Foo").unwrap(), "FOO");
        assert_eq!(upper(&"FOO").unwrap(), "FOO");
        assert_eq!(upper(&"FooBar").unwrap(), "FOOBAR");
        assert_eq!(upper(&"foo").unwrap(), "FOO");
    }

    #[test]
    fn test_trim() {
        assert_eq!(trim(&" Hello\tworld\t").unwrap(), "Hello\tworld");
    }

    #[test]
    fn test_join() {
        assert_eq!(
            join((&["hello", "world"]).into_iter(), ", ").unwrap(),
            "hello, world"
        );
        assert_eq!(join((&["hello"]).into_iter(), ", ").unwrap(), "hello");

        let empty: &[&str] = &[];
        assert_eq!(join(empty.into_iter(), ", ").unwrap(), "");

        let input: Vec<String> = vec!["foo".into(), "bar".into(), "bazz".into()];
        assert_eq!(
            join((&input).into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":").unwrap(),
            "foo:bar:bazz"
        );
        assert_eq!(
            join(input.clone().into_iter(), ":".to_string()).unwrap(),
            "foo:bar:bazz"
        );

        let input: &[String] = &["foo".into(), "bar".into()];
        assert_eq!(join(input.into_iter(), ":").unwrap(), "foo:bar");
        assert_eq!(join(input.into_iter(), ":".to_string()).unwrap(), "foo:bar");

        let real: String = "blah".into();
        let input: Vec<&str> = vec![&real];
        assert_eq!(join(input.into_iter(), ";").unwrap(), "blah");

        assert_eq!(
            join((&&&&&["foo", "bar"]).into_iter(), ", ").unwrap(),
            "foo, bar"
        );
    }

    #[test]
    fn test_abs() {
        assert_eq!(abs(1).unwrap(), 1);
        assert_eq!(abs(-1).unwrap(), 1);
        assert_eq!(abs(1.0).unwrap(), 1.0);
        assert_eq!(abs(-1.0).unwrap(), 1.0);
        assert_eq!(abs(1.0 as f64).unwrap(), 1.0 as f64);
        assert_eq!(abs(-1.0 as f64).unwrap(), 1.0 as f64);
    }

    #[test]
    fn test_capitalize() {
        assert_eq!(capitalize(&"foo").unwrap(), "Foo".to_string());
        assert_eq!(capitalize(&"f").unwrap(), "F".to_string());
        assert_eq!(capitalize(&"fO").unwrap(), "Fo".to_string());
        assert_eq!(capitalize(&"").unwrap(), "".to_string());
        assert_eq!(capitalize(&"FoO").unwrap(), "Foo".to_string());
        assert_eq!(capitalize(&"foO BAR").unwrap(), "Foo bar".to_string());
    }

    #[test]
    fn test_center() {
        assert_eq!(center(&"f", 3).unwrap(), " f ".to_string());
        assert_eq!(center(&"f", 4).unwrap(), " f  ".to_string());
        assert_eq!(center(&"foo", 1).unwrap(), "foo".to_string());
        assert_eq!(center(&"foo bar", 8).unwrap(), "foo bar ".to_string());
    }

    #[test]
    fn test_wordcount() {
        assert_eq!(wordcount(&"").unwrap(), 0);
        assert_eq!(wordcount(&" \n\t").unwrap(), 0);
        assert_eq!(wordcount(&"foo").unwrap(), 1);
        assert_eq!(wordcount(&"foo bar").unwrap(), 2);
    }
}
<|endoftext|>


<commit_before>
<commit_msg>boolean lit<commit_after>
use crate::grammar::ast::BooleanLit;
use crate::grammar::model::Fragment;
use nom::IResult;
use nom::branch::alt;
use nom::combinator::{value, map, recognize};
use nom::bytes::complete::tag;

impl<'s> BooleanLit<'s> {
    /// Literal representing a true value.
    pub const TRUE: &'static str = "true";

    /// Literal representing a false value.
    pub const FALSE: &'static str = "false";

    fn new(fr: Fragment<'s>, val: bool) -> Self {
        Self {frag: fr, inner: val}
    }

    fn parser_inner(inp: Fragment<'s>) -> IResult<Fragment<'s>, bool> {
        alt((
            value(true, tag(Self::TRUE)),
            value(false, tag(Self::FALSE))
        ))(inp)
    }

    /// Parses a boolean literal from wright source code.
    pub fn parse(input: Fragment<'s>) -> IResult<Fragment<'s>, Self> {
        map(recognize(Self::parser_inner), |fr: Fragment<'s>| {
            Self::new(fr, Self::parser_inner(fr).unwrap().1)
        })(input)
    }
}<|endoftext|>


<commit_before>//! Sensor related stuff.

use super::api;
use super::datastore::SafeDataStore;

/// A specification of a sensor.
///
/// The ``template`` field contains the static data of a sensor and
/// the ``data_key`` says how to find the sensor value in the datastore.
pub struct SensorSpec {
    pub template: Box<api::SensorTemplate>,
    pub data_key: String,
}

impl SensorSpec {

    /// Retrieve sensor value from the datastore.
    pub fn get_sensor_value(&self, datastore: &SafeDataStore) -> Option<String> {
        let datastore_lock = datastore.lock().unwrap();
        datastore_lock.retrieve(&self.data_key).map_err(|err| {
            warn!("Could not retrieve key '{}' from datastore, omiting the sensor", &self.data_key);
            err
        }).ok()
    }

}

<commit_msg>Log errors on debug level<commit_after>//! Sensor related stuff.

use super::api;
use super::datastore::SafeDataStore;

/// A specification of a sensor.
///
/// The ``template`` field contains the static data of a sensor and
/// the ``data_key`` says how to find the sensor value in the datastore.
pub struct SensorSpec {
    pub template: Box<api::SensorTemplate>,
    pub data_key: String,
}

impl SensorSpec {

    /// Retrieve sensor value from the datastore.
    pub fn get_sensor_value(&self, datastore: &SafeDataStore) -> Option<String> {
        let datastore_lock = datastore.lock().unwrap();
        datastore_lock.retrieve(&self.data_key).map_err(|err| {
            warn!("Could not retrieve key '{}' from datastore, omiting the sensor", &self.data_key);
            debug!("Error: {:?}", err);
            err
        }).ok()
    }

}

<|endoftext|>


<commit_before>extern crate desync;
extern crate futures;

use desync::Desync;

mod scheduler;
use self::scheduler::timeout::*;

use futures::prelude::*;
use futures::future;

use std::sync::*;
use std::time::*;
use std::thread::*;

#[derive(Debug)]
struct TestData {
    val: u32
}

#[test]
fn retrieve_data_synchronously() {
    let desynced = Desync::new(TestData { val: 0 });

    assert!(desynced.sync(|data| data.val) == 0);
}

#[test]
fn retrieve_data_into_local_var() {
    let desynced = Desync::new(TestData { val: 42 });
    let mut val = 0;

    desynced.sync(|data| val = data.val);

    assert!(val == 42);
}

#[test]
fn update_data_asynchronously() {
    let desynced = Desync::new(TestData { val: 0 });

    desynced.desync(|data| {
        sleep(Duration::from_millis(100));
        data.val = 42;
    });

    assert!(desynced.sync(|data| data.val) == 42);
}

#[test]
fn update_data_asynchronously_1000_times() {
    for _i in 0..1000 {
        timeout(|| {
            let desynced = Desync::new(TestData { val: 0 });

            desynced.desync(|data| {
                data.val = 42;
            });
            desynced.desync(|data| {
                data.val = 43;
            });

            assert!(desynced.sync(|data| data.val) == 43);
        }, 500);
    }
}

#[test]
fn update_data_with_future() {
    timeout(|| {
        use futures::executor;

        let desynced = Desync::new(TestData { val: 0 });

        desynced.desync(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });

        executor::block_on(async {
            let future = desynced.future(|data| { Box::pin(future::ready(data.val)) });
            assert!(future.await.unwrap() == 42);
        });
    }, 500);
}

#[test]
fn update_data_with_future_1000_times() {
    // Seems to timeout fairly reliably after signalling the future
    use futures::executor;

    for _i in 0..1000 {
        timeout(|| {
            let desynced = Desync::new(TestData { val: 0 });

            desynced.desync(|data| {
                data.val = 42;
            });
            desynced.desync(|data| {
                data.val = 43;
            });

            executor::block_on(async {
                let future = desynced.future(|data| Box::pin(future::ready(data.val)));

                assert!(future.await.unwrap() == 43);
            });
        }, 500);
    }
}

#[test]
fn dropping_while_running_isnt_obviously_bad() {
    let desynced = Desync::new(TestData { val: 0 });

    desynced.desync(|data| {
        sleep(Duration::from_millis(100));
        data.val = 42;
    });
    desynced.desync(|data| {
        sleep(Duration::from_millis(100));
        data.val = 42;
    });
}

#[test]
fn wait_for_future() {
    // TODO: occasional test failure that happens if the future 'arrives' before the queue is empty
    // (Because we need a future that arrives when the queue is actually suspended)
    timeout(|| {
        use futures::executor;
        use futures::channel::oneshot;

        // We use a oneshot as our future, and a mpsc channel to track progress
        let desynced                = Desync::new(0);
        let (future_tx, future_rx)  = oneshot::channel();

        // First value 0 -> 1
        desynced.desync(|val| {
            // Sleep here so the future should be waiting for us
            sleep(Duration::from_millis(100));
            assert!(*val == 0);
            *val = 1;
        });

        // Future should go 1 -> 2, but takes whatever future_tx sends
        let future = desynced.after(future_rx, |val, future_result| {
            assert!(*val == 1);
            *val = future_result.unwrap();

            // Return '4' to anything listening for this future
            4
        });

        // Finally, 3
        desynced.desync(move |val| { assert!(*val == 2); *val = 3 });

        executor::block_on(async {
            // Send '2' to the future
            future_tx.send(2).unwrap();

            // Future should resolve to 4
            assert!(future.await == Ok(4));

            // Final value should be 3
            assert!(desynced.sync(|val| *val) == 3);
        })
    }, 500);
}

#[test]
fn future_and_sync() {
    // This test seems to produce different behaviour if it's run by itself (this sleep tends to force it to run after the other tests and thus fail)
    // So far the failure seems reliable when this test is running exclusively
    sleep(Duration::from_millis(1000));

    use std::thread;
    use futures::prelude::*;
    use futures::channel::oneshot;

    // The idea here is we perform an action with a future() and read the result back with a sync() (which is a way you can mix-and-match
    // programming models with desync)
    //
    // The 'core' runs a request as a future, waiting for the channel result. We store the result in sync_request, and then retrieve
    // it again by calling sync - as Desync always runs things sequentially, it guarantees the ordering (something that's much harder
    // to achieve with a mutex)
    let (send, recv)    = oneshot::channel::<i32>();
    let core            = Desync::new(0);
    let sync_request    = Desync::new(None);

    // Send a request to the 'core' via the sync reqeust and store the result
    let _ = sync_request.future(move |data| {
        async move {
            let result = core.future(move |_core| {
                async move {
                    Some(recv.await.unwrap())
                }.boxed()
            }).await;

            *data = result.unwrap();
        }.boxed()
    });

    // Signal the future after a delay
    thread::spawn(move || {
        thread::sleep(Duration::from_millis(50));
        send.send(42).ok();
    });

    // Retrieve the result once the future completes
    let result = sync_request.sync(|req| req.take());

    // Should retrieve the value generated in the future
    assert!(result == Some(42));
}

#[test]
fn double_future_and_sync() {
    use std::thread;

    // This test will queue two futures here, each of which will need to return to another desync
    // If two futures are scheduled and triggered in a row when draining a queue that both signal
    let core        = Arc::new(Desync::new(()));

    let initiator_1 = Desync::new(None);
    let initiator_2 = Desync::new(None);
    let initiator_3 = Desync::new(None);

    let core_1      = Arc::clone(&core);
    let _           = initiator_1.future(move |val| {
        async move {
            // Wait for a task on the core
            *val = core_1.future(move |_| {
                async move { thread::sleep(Duration::from_millis(400)); Some(1) }.boxed()
            }).await.unwrap();
        }.boxed()
    });

    let core_2      = Arc::clone(&core);
    let _           = initiator_2.future(move |val| {
        async move {
            // Wait for the original initiator to start its future
            thread::sleep(Duration::from_millis(100));

            // Wait for a task on the core
            *val = core_2.future(move |_| {
                async move { thread::sleep(Duration::from_millis(200)); Some(2) }.boxed()
            }).await.unwrap();
        }.boxed()
    });

    let core_3      = Arc::clone(&core);
    let _           = initiator_3.future(move |val| {
        async move {
            // Wait for the original initiator to start its future
            thread::sleep(Duration::from_millis(200));

            // Wait for a task on the core
            *val = core_3.future(move |_| {
                async move { thread::sleep(Duration::from_millis(200)); Some(3) }.boxed()
            }).await.unwrap();
        }.boxed()
    });

    // Wait for the result from the futures synchronously
    assert!(initiator_3.sync(|val| { *val }) == Some(3));
    assert!(initiator_2.sync(|val| { *val }) == Some(2));
    assert!(initiator_1.sync(|val| { *val }) == Some(1));
}
<commit_msg>Add TODO for this test<commit_after>extern crate desync;
extern crate futures;

use desync::Desync;

mod scheduler;
use self::scheduler::timeout::*;

use futures::prelude::*;
use futures::future;

use std::sync::*;
use std::time::*;
use std::thread::*;

#[derive(Debug)]
struct TestData {
    val: u32
}

#[test]
fn retrieve_data_synchronously() {
    let desynced = Desync::new(TestData { val: 0 });

    assert!(desynced.sync(|data| data.val) == 0);
}

#[test]
fn retrieve_data_into_local_var() {
    let desynced = Desync::new(TestData { val: 42 });
    let mut val = 0;

    desynced.sync(|data| val = data.val);

    assert!(val == 42);
}

#[test]
fn update_data_asynchronously() {
    let desynced = Desync::new(TestData { val: 0 });

    desynced.desync(|data| {
        sleep(Duration::from_millis(100));
        data.val = 42;
    });

    assert!(desynced.sync(|data| data.val) == 42);
}

#[test]
fn update_data_asynchronously_1000_times() {
    for _i in 0..1000 {
        timeout(|| {
            let desynced = Desync::new(TestData { val: 0 });

            desynced.desync(|data| {
                data.val = 42;
            });
            desynced.desync(|data| {
                data.val = 43;
            });

            assert!(desynced.sync(|data| data.val) == 43);
        }, 500);
    }
}

#[test]
fn update_data_with_future() {
    timeout(|| {
        use futures::executor;

        let desynced = Desync::new(TestData { val: 0 });

        desynced.desync(|data| {
            sleep(Duration::from_millis(100));
            data.val = 42;
        });

        executor::block_on(async {
            let future = desynced.future(|data| { Box::pin(future::ready(data.val)) });
            assert!(future.await.unwrap() == 42);
        });
    }, 500);
}

#[test]
fn update_data_with_future_1000_times() {
    // Seems to timeout fairly reliably after signalling the future
    use futures::executor;

    for _i in 0..1000 {
        timeout(|| {
            let desynced = Desync::new(TestData { val: 0 });

            desynced.desync(|data| {
                data.val = 42;
            });
            desynced.desync(|data| {
                data.val = 43;
            });

            executor::block_on(async {
                let future = desynced.future(|data| Box::pin(future::ready(data.val)));

                assert!(future.await.unwrap() == 43);
            });
        }, 500);
    }
}

#[test]
fn dropping_while_running_isnt_obviously_bad() {
    let desynced = Desync::new(TestData { val: 0 });

    desynced.desync(|data| {
        sleep(Duration::from_millis(100));
        data.val = 42;
    });
    desynced.desync(|data| {
        sleep(Duration::from_millis(100));
        data.val = 42;
    });
}

#[test]
fn wait_for_future() {
    // TODO: occasional test failure that happens if the future 'arrives' before the queue is empty
    // (Because we need a future that arrives when the queue is actually suspended)
    timeout(|| {
        use futures::executor;
        use futures::channel::oneshot;

        // We use a oneshot as our future, and a mpsc channel to track progress
        let desynced                = Desync::new(0);
        let (future_tx, future_rx)  = oneshot::channel();

        // First value 0 -> 1
        desynced.desync(|val| {
            // Sleep here so the future should be waiting for us
            sleep(Duration::from_millis(100));
            assert!(*val == 0);
            *val = 1;
        });

        // Future should go 1 -> 2, but takes whatever future_tx sends
        let future = desynced.after(future_rx, |val, future_result| {
            assert!(*val == 1);
            *val = future_result.unwrap();

            // Return '4' to anything listening for this future
            4
        });

        // Finally, 3
        desynced.desync(move |val| { assert!(*val == 2); *val = 3 });

        executor::block_on(async {
            // Send '2' to the future
            future_tx.send(2).unwrap();

            // Future should resolve to 4
            assert!(future.await == Ok(4));

            // Final value should be 3
            assert!(desynced.sync(|val| *val) == 3);
        })
    }, 500);
}

#[test]
fn future_and_sync() {
    // This test seems to produce different behaviour if it's run by itself (this sleep tends to force it to run after the other tests and thus fail)
    // So far the failure seems reliable when this test is running exclusively
    sleep(Duration::from_millis(1000));

    use std::thread;
    use futures::prelude::*;
    use futures::channel::oneshot;

    // The idea here is we perform an action with a future() and read the result back with a sync() (which is a way you can mix-and-match
    // programming models with desync)
    //
    // The 'core' runs a request as a future, waiting for the channel result. We store the result in sync_request, and then retrieve
    // it again by calling sync - as Desync always runs things sequentially, it guarantees the ordering (something that's much harder
    // to achieve with a mutex)
    let (send, recv)    = oneshot::channel::<i32>();
    let core            = Desync::new(0);
    let sync_request    = Desync::new(None);

    // Send a request to the 'core' via the sync reqeust and store the result
    let _ = sync_request.future(move |data| {
        async move {
            let result = core.future(move |_core| {
                async move {
                    Some(recv.await.unwrap())
                }.boxed()
            }).await;

            *data = result.unwrap();
        }.boxed()
    });

    // Signal the future after a delay
    thread::spawn(move || {
        thread::sleep(Duration::from_millis(50));
        send.send(42).ok();
    });

    // Retrieve the result once the future completes
    let result = sync_request.sync(|req| req.take());

    // Should retrieve the value generated in the future
    assert!(result == Some(42));
}

#[test]
fn double_future_and_sync() {
    use std::thread;

    // TODO: signal with channels instead of using thread::sleep

    // This test will queue two futures here, each of which will need to return to another desync
    // If two futures are scheduled and triggered in a row when draining a queue that both signal
    let core        = Arc::new(Desync::new(()));

    let initiator_1 = Desync::new(None);
    let initiator_2 = Desync::new(None);
    let initiator_3 = Desync::new(None);

    let core_1      = Arc::clone(&core);
    let _           = initiator_1.future(move |val| {
        async move {
            // Wait for a task on the core
            *val = core_1.future(move |_| {
                async move { thread::sleep(Duration::from_millis(400)); Some(1) }.boxed()
            }).await.unwrap();
        }.boxed()
    });

    let core_2      = Arc::clone(&core);
    let _           = initiator_2.future(move |val| {
        async move {
            // Wait for the original initiator to start its future
            thread::sleep(Duration::from_millis(100));

            // Wait for a task on the core
            *val = core_2.future(move |_| {
                async move { thread::sleep(Duration::from_millis(200)); Some(2) }.boxed()
            }).await.unwrap();
        }.boxed()
    });

    let core_3      = Arc::clone(&core);
    let _           = initiator_3.future(move |val| {
        async move {
            // Wait for the original initiator to start its future
            thread::sleep(Duration::from_millis(200));

            // Wait for a task on the core
            *val = core_3.future(move |_| {
                async move { thread::sleep(Duration::from_millis(200)); Some(3) }.boxed()
            }).await.unwrap();
        }.boxed()
    });

    // Wait for the result from the futures synchronously
    assert!(initiator_3.sync(|val| { *val }) == Some(3));
    assert!(initiator_2.sync(|val| { *val }) == Some(2));
    assert!(initiator_1.sync(|val| { *val }) == Some(1));
}
<|endoftext|>


<commit_before>#![deny(unused_must_use)]

#[macro_use]
extern crate diesel;

use diesel::*;

table! {
    stuff (b) {
        b -> Bool,
    }
}

fn main() {
    use stuff::table as st;
    use stuff::b;

    st.select(b); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.select(b).distinct(); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.count(); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.order(b); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.limit(1); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.offset(1); //~ ERROR unused `diesel::query_builder::SelectStatement`

    st.filter(b.eq(true)); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.filter(b.eq(true)).limit(1); //~ ERROR unused `diesel::query_builder::SelectStatement`

    insert_into(stuff)
        .values(b.eq(true)); //- ERROR unused `diesel::query_builder::InsertStatement`
    insert_into(stuff)
        .values(&vec![b.eq(true), b.eq(false)]); //~ ERROR unused `diesel::query_builder::InsertStatement`

    update(stuff).set(b.eq(true)); //~ ERROR unused `diesel::query_builder::UpdateStatement`

    delete(stuff); //~ ERROR unused `diesel::query_builder::DeleteStatement`

    let _thingies = st.filter(b.eq(true)); // No ERROR
}
<commit_msg>Fix failing must_use test<commit_after>#![deny(unused_must_use)]

#[macro_use]
extern crate diesel;

use diesel::*;

table! {
    stuff (b) {
        b -> Bool,
    }
}

fn main() {
    use stuff::b;
    use stuff::table as st;

    st.select(b); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.select(b).distinct(); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.count(); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.order(b); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.limit(1); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.offset(1); //~ ERROR unused `diesel::query_builder::SelectStatement`

    st.filter(b.eq(true)); //~ ERROR unused `diesel::query_builder::SelectStatement`
    st.filter(b.eq(true)).limit(1); //~ ERROR unused `diesel::query_builder::SelectStatement`

    insert_into(st).values(b.eq(true)); //~ ERROR unused
    insert_into(st).values(&vec![b.eq(true), b.eq(false)]); //~ ERROR unused

    update(st).set(b.eq(true)); //~ ERROR unused

    delete(st); //~ ERROR unused

    let _thingies = st.filter(b.eq(true)); // No ERROR
}
<|endoftext|>