<commit_before>extern crate base64;
use std::str;

#[test]
fn test_encode_decode_valid() {
    let mut out = [0u8; 256];
    let examples = [
        // empty
        ("", ""),
        // no padding chars
        ("qwe", "cXdl"),
        // one padding char
        ("qw", "cXc="),
        // two apdding chars
        ("q", "cQ=="),
        // all bytes from 0 to 127
        ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\
          \x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\'\
          ()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefgh\
          ijklmnopqrstuvwxyz{|}~\x7f",
         "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEy\
          MzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2Rl\
          ZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8="
        ),
    ];

    for &(data, encoded) in examples.iter() {
        let count = base64::encode(data.as_bytes(), &mut out);
        assert_eq!(
            str::from_utf8(&out[..count]),
            str::from_utf8(&encoded.as_bytes())
        );
        let count = base64::decode(encoded.as_bytes(), &mut out).unwrap();
        assert_eq!(
            str::from_utf8(&out[..count]),
            str::from_utf8(&data.as_bytes())
        )
    }
}

#[test]
fn test_decode() {
    let mut out = [0u8; 256];

    let examples = [
        (Ok("qw"), "\n\n\nc\nX\nc\n="),
        (Err("Invalid padding"), "cXc"),
        (Err("Invalid character"), "cXc&"),
    ];

    for &(data, encoded) in examples.iter() {
        let res = base64::decode(encoded.as_bytes(), &mut out);
        match (res, out, data) {
            (Ok(count), res, Ok(data)) => assert_eq!(
                str::from_utf8(&out[..count]).unwrap(),
                data
            ),
            (Ok(_), _, Err(msg)) => panic!(
                "base64::decode return Ok when Err({}) expected",
                msg
            ),
            (Err(msg), _, Ok(_)) => panic!(
                "base64::decode return Err({}) when it not expected",
                msg
            ),
            (Err(msg), _, Err(expected)) => assert_eq!(
                msg, expected
            )
        }
    }
}
<commit_msg>fix unused variable in test<commit_after>extern crate base64;
use std::str;

#[test]
fn test_encode_decode_valid() {
    let mut out = [0u8; 256];
    let examples = [
        // empty
        ("", ""),
        // no padding chars
        ("qwe", "cXdl"),
        // one padding char
        ("qw", "cXc="),
        // two apdding chars
        ("q", "cQ=="),
        // all bytes from 0 to 127
        ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\
          \x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\'\
          ()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefgh\
          ijklmnopqrstuvwxyz{|}~\x7f",
         "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEy\
          MzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2Rl\
          ZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8="
        ),
    ];

    for &(data, encoded) in examples.iter() {
        let count = base64::encode(data.as_bytes(), &mut out);
        assert_eq!(
            str::from_utf8(&out[..count]),
            str::from_utf8(&encoded.as_bytes())
        );
        let count = base64::decode(encoded.as_bytes(), &mut out).unwrap();
        assert_eq!(
            str::from_utf8(&out[..count]),
            str::from_utf8(&data.as_bytes())
        )
    }
}

#[test]
fn test_decode() {
    let mut out = [0u8; 256];

    let examples = [
        (Ok("qw"), "\n\n\nc\nX\nc\n="),
        (Err("Invalid padding"), "cXc"),
        (Err("Invalid character"), "cXc&"),
    ];

    for &(data, encoded) in examples.iter() {
        let res = base64::decode(encoded.as_bytes(), &mut out);
        match (res, out, data) {
            (Ok(count), _, Ok(data)) => assert_eq!(
                str::from_utf8(&out[..count]).unwrap(),
                data
            ),
            (Ok(_), _, Err(msg)) => panic!(
                "base64::decode return Ok when Err({}) expected",
                msg
            ),
            (Err(msg), _, Ok(_)) => panic!(
                "base64::decode return Err({}) when it not expected",
                msg
            ),
            (Err(msg), _, Err(expected)) => assert_eq!(
                msg, expected
            )
        }
    }
}
<|endoftext|>


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

#![allow(dead_code)]

use std; // To refer to std::result::Result.

use std::collections::BTreeSet;

use rusqlite;

use edn;

use core_traits::{
    Attribute,
    ValueType,
};

use db_traits::errors::DbError;
use query_algebrizer_traits::errors::{
    AlgebrizerError,
};
use query_projector_traits::errors::{
    ProjectorError,
};
use query_pull_traits::errors::{
    PullError,
};
use sql_traits::errors::{
    SQLError,
};

#[cfg(feature = "syncable")]
use tolstoy_traits::errors::{
    TolstoyError,
};

pub type Result<T> = std::result::Result<T, MentatError>;

#[derive(Debug, Fail)]
pub enum MentatError {
    #[fail(display = "bad uuid {}", _0)]
    BadUuid(String),

    #[fail(display = "path {} already exists", _0)]
    PathAlreadyExists(String),

    #[fail(display = "variables {:?} unbound at query execution time", _0)]
    UnboundVariables(BTreeSet<String>),

    #[fail(display = "invalid argument name: '{}'", _0)]
    InvalidArgumentName(String),

    #[fail(display = "unknown attribute: '{}'", _0)]
    UnknownAttribute(String),

    #[fail(display = "invalid vocabulary version")]
    InvalidVocabularyVersion,

    #[fail(display = "vocabulary {}/version {} already has attribute {}, and the requested definition differs", _0, _1, _2)]
    ConflictingAttributeDefinitions(String, u32, String, Attribute, Attribute),

    #[fail(display = "existing vocabulary {} too new: wanted version {}, got version {}", _0, _1, _2)]
    ExistingVocabularyTooNew(String, u32, u32),

    #[fail(display = "core schema: wanted version {}, got version {:?}", _0, _1)]
    UnexpectedCoreSchema(u32, Option<u32>),

    #[fail(display = "Lost the transact() race!")]
    UnexpectedLostTransactRace,

    #[fail(display = "missing core attribute {}", _0)]
    MissingCoreVocabulary(edn::query::Keyword),

    #[fail(display = "schema changed since query was prepared")]
    PreparedQuerySchemaMismatch,

    #[fail(display = "provided value of type {} doesn't match attribute value type {}", _0, _1)]
    ValueTypeMismatch(ValueType, ValueType),

    #[fail(display = "{}", _0)]
    IoError(#[cause] std::io::Error),

    // It would be better to capture the underlying `rusqlite::Error`, but that type doesn't
    // implement many useful traits, including `Clone`, `Eq`, and `PartialEq`.
    #[fail(display = "SQL error: {}", _0)]
    RusqliteError(String),

    #[fail(display = "{}", _0)]
    EdnParseError(#[cause] edn::ParseError),

    #[fail(display = "{}", _0)]
    DbError(#[cause] DbError),

    #[fail(display = "{}", _0)]
    AlgebrizerError(#[cause] AlgebrizerError),

    #[fail(display = "{}", _0)]
    ProjectorError(#[cause] ProjectorError),

    #[fail(display = "{}", _0)]
    PullError(#[cause] PullError),

    #[fail(display = "{}", _0)]
    SQLError(#[cause] SQLError),

    #[cfg(feature = "syncable")]
    #[fail(display = "{}", _0)]
    TolstoyError(#[cause] TolstoyError),
}

impl From<std::io::Error> for MentatError {
    fn from(error: std::io::Error) -> MentatError {
        MentatError::IoError(error)
    }
}

impl From<rusqlite::Error> for MentatError {
    fn from(error: rusqlite::Error) -> MentatError {
        MentatError::RusqliteError(error.to_string())
    }
}

impl From<edn::ParseError> for MentatError {
    fn from(error: edn::ParseError) -> MentatError {
        MentatError::EdnParseError(error)
    }
}

impl From<DbError> for MentatError {
    fn from(error: DbError) -> MentatError {
        MentatError::DbError(error)
    }
}

impl From<AlgebrizerError> for MentatError {
    fn from(error: AlgebrizerError) -> MentatError {
        MentatError::AlgebrizerError(error)
    }
}

impl From<ProjectorError> for MentatError {
    fn from(error: ProjectorError) -> MentatError {
        MentatError::ProjectorError(error)
    }
}

impl From<PullError> for MentatError {
    fn from(error: PullError) -> MentatError {
        MentatError::PullError(error)
    }
}

impl From<SQLError> for MentatError {
    fn from(error: SQLError) -> MentatError {
        MentatError::SQLError(error)
    }
}

#[cfg(feature = "syncable")]
impl From<TolstoyError> for MentatError {
    fn from(error: TolstoyError) -> MentatError {
        MentatError::TolstoyError(error)
    }
}
<commit_msg>Pre: Add top-level NotYetImplemented error.<commit_after>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#![allow(dead_code)]

use std; // To refer to std::result::Result.

use std::collections::BTreeSet;

use rusqlite;

use edn;

use core_traits::{
    Attribute,
    ValueType,
};

use db_traits::errors::DbError;
use query_algebrizer_traits::errors::{
    AlgebrizerError,
};
use query_projector_traits::errors::{
    ProjectorError,
};
use query_pull_traits::errors::{
    PullError,
};
use sql_traits::errors::{
    SQLError,
};

#[cfg(feature = "syncable")]
use tolstoy_traits::errors::{
    TolstoyError,
};

pub type Result<T> = std::result::Result<T, MentatError>;

#[derive(Debug, Fail)]
pub enum MentatError {
    #[fail(display = "bad uuid {}", _0)]
    BadUuid(String),

    #[fail(display = "path {} already exists", _0)]
    PathAlreadyExists(String),

    #[fail(display = "variables {:?} unbound at query execution time", _0)]
    UnboundVariables(BTreeSet<String>),

    #[fail(display = "invalid argument name: '{}'", _0)]
    InvalidArgumentName(String),

    #[fail(display = "unknown attribute: '{}'", _0)]
    UnknownAttribute(String),

    #[fail(display = "invalid vocabulary version")]
    InvalidVocabularyVersion,

    #[fail(display = "vocabulary {}/version {} already has attribute {}, and the requested definition differs", _0, _1, _2)]
    ConflictingAttributeDefinitions(String, u32, String, Attribute, Attribute),

    #[fail(display = "existing vocabulary {} too new: wanted version {}, got version {}", _0, _1, _2)]
    ExistingVocabularyTooNew(String, u32, u32),

    #[fail(display = "core schema: wanted version {}, got version {:?}", _0, _1)]
    UnexpectedCoreSchema(u32, Option<u32>),

    #[fail(display = "Lost the transact() race!")]
    UnexpectedLostTransactRace,

    #[fail(display = "missing core attribute {}", _0)]
    MissingCoreVocabulary(edn::query::Keyword),

    #[fail(display = "schema changed since query was prepared")]
    PreparedQuerySchemaMismatch,

    #[fail(display = "provided value of type {} doesn't match attribute value type {}", _0, _1)]
    ValueTypeMismatch(ValueType, ValueType),

    #[fail(display = "{}", _0)]
    IoError(#[cause] std::io::Error),

    /// We're just not done yet.  Message that the feature is recognized but not yet
    /// implemented.
    #[fail(display = "not yet implemented: {}", _0)]
    NotYetImplemented(String),

    // It would be better to capture the underlying `rusqlite::Error`, but that type doesn't
    // implement many useful traits, including `Clone`, `Eq`, and `PartialEq`.
    #[fail(display = "SQL error: {}", _0)]
    RusqliteError(String),

    #[fail(display = "{}", _0)]
    EdnParseError(#[cause] edn::ParseError),

    #[fail(display = "{}", _0)]
    DbError(#[cause] DbError),

    #[fail(display = "{}", _0)]
    AlgebrizerError(#[cause] AlgebrizerError),

    #[fail(display = "{}", _0)]
    ProjectorError(#[cause] ProjectorError),

    #[fail(display = "{}", _0)]
    PullError(#[cause] PullError),

    #[fail(display = "{}", _0)]
    SQLError(#[cause] SQLError),

    #[cfg(feature = "syncable")]
    #[fail(display = "{}", _0)]
    TolstoyError(#[cause] TolstoyError),
}

impl From<std::io::Error> for MentatError {
    fn from(error: std::io::Error) -> MentatError {
        MentatError::IoError(error)
    }
}

impl From<rusqlite::Error> for MentatError {
    fn from(error: rusqlite::Error) -> MentatError {
        MentatError::RusqliteError(error.to_string())
    }
}

impl From<edn::ParseError> for MentatError {
    fn from(error: edn::ParseError) -> MentatError {
        MentatError::EdnParseError(error)
    }
}

impl From<DbError> for MentatError {
    fn from(error: DbError) -> MentatError {
        MentatError::DbError(error)
    }
}

impl From<AlgebrizerError> for MentatError {
    fn from(error: AlgebrizerError) -> MentatError {
        MentatError::AlgebrizerError(error)
    }
}

impl From<ProjectorError> for MentatError {
    fn from(error: ProjectorError) -> MentatError {
        MentatError::ProjectorError(error)
    }
}

impl From<PullError> for MentatError {
    fn from(error: PullError) -> MentatError {
        MentatError::PullError(error)
    }
}

impl From<SQLError> for MentatError {
    fn from(error: SQLError) -> MentatError {
        MentatError::SQLError(error)
    }
}

#[cfg(feature = "syncable")]
impl From<TolstoyError> for MentatError {
    fn from(error: TolstoyError) -> MentatError {
        MentatError::TolstoyError(error)
    }
}
<|endoftext|>


<commit_before>extern crate actix;
extern crate actix_web;
extern crate tokio_core;
extern crate reqwest;
extern crate futures;
extern crate h2;
extern crate http;

use std::{net, thread, time};
use std::sync::{Arc, mpsc};
use std::sync::atomic::{AtomicUsize, Ordering};
use futures::Future;
use h2::client;
use http::Request;
use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;

use actix_web::*;
use actix::System;

#[test]
fn test_start() {
    let _ = test::TestServer::unused_addr();
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let sys = System::new("test");
        let srv = HttpServer::new(
            || vec![Application::new()
                    .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk))]);

        let srv = srv.bind("127.0.0.1:0").unwrap();
        let addr = srv.addrs()[0];
        let srv_addr = srv.start();
        let _ = tx.send((addr, srv_addr));
        sys.run();
    });
    let (addr, srv_addr) = rx.recv().unwrap();
    assert!(reqwest::get(&format!("http://{}/", addr)).unwrap().status().is_success());

    // pause
    let _ = srv_addr.call_fut(dev::PauseServer).wait();
    thread::sleep(time::Duration::from_millis(100));
    assert!(net::TcpStream::connect(addr).is_err());

    // resume
    let _ = srv_addr.call_fut(dev::ResumeServer).wait();
    assert!(reqwest::get(&format!("http://{}/", addr)).unwrap().status().is_success());
}

#[test]
fn test_simple() {
    let srv = test::TestServer::new(|app| app.handler(httpcodes::HTTPOk));
    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
}

#[test]
fn test_h2() {
    let srv = test::TestServer::new(|app| app.handler(httpcodes::HTTPOk));
    let addr = srv.addr();

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let tcp = TcpStream::connect(&addr, &handle);

    let tcp = tcp.then(|res| {
        client::handshake(res.unwrap())
    }).then(move |res| {
        let (mut client, h2) = res.unwrap();

        let request = Request::builder()
            .uri(format!("https://{}/", addr).as_str())
            .body(())
            .unwrap();
        let (response, _) = client.send_request(request, false).unwrap();

        // Spawn a task to run the conn...
        handle.spawn(h2.map_err(|e| println!("GOT ERR={:?}", e)));

        response
    });
    let resp = core.run(tcp).unwrap();
    assert_eq!(resp.status(), StatusCode::OK);
}

#[test]
fn test_application() {
    let srv = test::TestServer::with_factory(
        || Application::new().resource("/", |r| r.h(httpcodes::HTTPOk)));
    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
}

struct MiddlewareTest {
    start: Arc<AtomicUsize>,
    response: Arc<AtomicUsize>,
    finish: Arc<AtomicUsize>,
}

impl<S> middleware::Middleware<S> for MiddlewareTest {
    fn start(&self, _: &mut HttpRequest<S>) -> Result<middleware::Started> {
        self.start.store(self.start.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
        Ok(middleware::Started::Done)
    }

    fn response(&self, _: &mut HttpRequest<S>, resp: HttpResponse) -> Result<middleware::Response> {
        self.response.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
        Ok(middleware::Response::Done(resp))
    }

    fn finish(&self, _: &mut HttpRequest<S>, _: &HttpResponse) -> middleware::Finished {
        self.finish.store(self.finish.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
        middleware::Finished::Done
    }
}

#[test]
fn test_middlewares() {
    let num1 = Arc::new(AtomicUsize::new(0));
    let num2 = Arc::new(AtomicUsize::new(0));
    let num3 = Arc::new(AtomicUsize::new(0));

    let act_num1 = Arc::clone(&num1);
    let act_num2 = Arc::clone(&num2);
    let act_num3 = Arc::clone(&num3);

    let srv = test::TestServer::new(
        move |app| app.middleware(MiddlewareTest{start: Arc::clone(&act_num1),
                                                 response: Arc::clone(&act_num2),
                                                 finish: Arc::clone(&act_num3)})
            .handler(httpcodes::HTTPOk)
    );

    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
    assert_eq!(num1.load(Ordering::Relaxed), 1);
    assert_eq!(num2.load(Ordering::Relaxed), 1);
    assert_eq!(num3.load(Ordering::Relaxed), 1);
}

#[test]
fn test_resource_middlewares() {
    let num1 = Arc::new(AtomicUsize::new(0));
    let num2 = Arc::new(AtomicUsize::new(0));
    let num3 = Arc::new(AtomicUsize::new(0));

    let act_num1 = Arc::clone(&num1);
    let act_num2 = Arc::clone(&num2);
    let act_num3 = Arc::clone(&num3);

    let srv = test::TestServer::new(
        move |app| app.handler2(
            httpcodes::HTTPOk,
            MiddlewareTest{start: Arc::clone(&act_num1),
                           response: Arc::clone(&act_num2),
                           finish: Arc::clone(&act_num3)})
    );

    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
    assert_eq!(num1.load(Ordering::Relaxed), 1);
    assert_eq!(num2.load(Ordering::Relaxed), 1);
    // assert_eq!(num3.load(Ordering::Relaxed), 1);
}
<commit_msg>encoding tests<commit_after>extern crate actix;
extern crate actix_web;
extern crate tokio_core;
extern crate reqwest;
extern crate futures;
extern crate h2;
extern crate http;
extern crate bytes;
extern crate flate2;
extern crate brotli2;

use std::{net, thread, time};
use std::io::Write;
use std::sync::{Arc, mpsc};
use std::sync::atomic::{AtomicUsize, Ordering};
use flate2::Compression;
use flate2::write::{GzEncoder, DeflateEncoder};
use brotli2::write::BrotliEncoder;
use futures::Future;
use h2::client;
use bytes::{Bytes, BytesMut, BufMut};
use http::Request;
use tokio_core::net::TcpStream;
use tokio_core::reactor::Core;
use reqwest::header::{Encoding, ContentEncoding};

use actix_web::*;
use actix::System;

const STR: &str =
    "Hello World Hello World Hello World Hello World Hello World \
     Hello World Hello World Hello World Hello World Hello World \
     Hello World Hello World Hello World Hello World Hello World \
     Hello World Hello World Hello World Hello World Hello World \
     Hello World Hello World Hello World Hello World Hello World";

#[test]
fn test_start() {
    let _ = test::TestServer::unused_addr();
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let sys = System::new("test");
        let srv = HttpServer::new(
            || vec![Application::new()
                    .resource("/", |r| r.method(Method::GET).h(httpcodes::HTTPOk))]);

        let srv = srv.bind("127.0.0.1:0").unwrap();
        let addr = srv.addrs()[0];
        let srv_addr = srv.start();
        let _ = tx.send((addr, srv_addr));
        sys.run();
    });
    let (addr, srv_addr) = rx.recv().unwrap();
    assert!(reqwest::get(&format!("http://{}/", addr)).unwrap().status().is_success());

    // pause
    let _ = srv_addr.call_fut(dev::PauseServer).wait();
    thread::sleep(time::Duration::from_millis(100));
    assert!(net::TcpStream::connect(addr).is_err());

    // resume
    let _ = srv_addr.call_fut(dev::ResumeServer).wait();
    assert!(reqwest::get(&format!("http://{}/", addr)).unwrap().status().is_success());
}

#[test]
fn test_simple() {
    let srv = test::TestServer::new(|app| app.handler(httpcodes::HTTPOk));
    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
}

#[test]
fn test_body() {
    let srv = test::TestServer::new(
        |app| app.handler(|_| httpcodes::HTTPOk.build().body(STR)));
    let mut res = reqwest::get(&srv.url("/")).unwrap();
    assert!(res.status().is_success());
    let mut bytes = BytesMut::with_capacity(1024).writer();
    let _ = res.copy_to(&mut bytes);
    let bytes = bytes.into_inner();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_body_deflate() {
    let srv = test::TestServer::new(
        |app| app.handler(
            |_| httpcodes::HTTPOk
                .build()
                .content_encoding(headers::ContentEncoding::Deflate)
                .body(STR)));
    let mut res = reqwest::get(&srv.url("/")).unwrap();
    assert!(res.status().is_success());
    let mut bytes = BytesMut::with_capacity(1024).writer();
    let _ = res.copy_to(&mut bytes);
    let bytes = bytes.into_inner();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_body_brotli() {
    let srv = test::TestServer::new(
        |app| app.handler(
            |_| httpcodes::HTTPOk
                .build()
                .content_encoding(headers::ContentEncoding::Br)
                .body(STR)));
    let mut res = reqwest::get(&srv.url("/")).unwrap();
    assert!(res.status().is_success());
    let mut bytes = BytesMut::with_capacity(1024).writer();
    let _ = res.copy_to(&mut bytes);
    let bytes = bytes.into_inner();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_h2() {
    let srv = test::TestServer::new(|app| app.handler(httpcodes::HTTPOk));
    let addr = srv.addr();

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let tcp = TcpStream::connect(&addr, &handle);

    let tcp = tcp.then(|res| {
        client::handshake(res.unwrap())
    }).then(move |res| {
        let (mut client, h2) = res.unwrap();

        let request = Request::builder()
            .uri(format!("https://{}/", addr).as_str())
            .body(())
            .unwrap();
        let (response, _) = client.send_request(request, false).unwrap();

        // Spawn a task to run the conn...
        handle.spawn(h2.map_err(|e| println!("GOT ERR={:?}", e)));

        response
    });
    let resp = core.run(tcp).unwrap();
    assert_eq!(resp.status(), StatusCode::OK);
}

#[test]
fn test_gzip_encoding() {
    let srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
        req.body()
            .and_then(|bytes: Bytes| {
                Ok(httpcodes::HTTPOk
                   .build()
                   .content_encoding(headers::ContentEncoding::Identity)
                   .body(bytes))
            }).responder()}
    ));

    let mut e = GzEncoder::new(Vec::new(), Compression::default());
    e.write_all(STR.as_ref()).unwrap();
    let enc = e.finish().unwrap();

    let client = reqwest::Client::new();
    let mut res = client.post(&srv.url("/"))
        .header(ContentEncoding(vec![Encoding::Gzip]))
        .body(enc.clone()).send().unwrap();
    let mut bytes = BytesMut::with_capacity(1024).writer();
    let _ = res.copy_to(&mut bytes);
    let bytes = bytes.into_inner();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_deflate_encoding() {
    let srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
        req.body()
            .and_then(|bytes: Bytes| {
                Ok(httpcodes::HTTPOk
                   .build()
                   .content_encoding(headers::ContentEncoding::Identity)
                   .body(bytes))
            }).responder()}
    ));

    let mut e = DeflateEncoder::new(Vec::new(), Compression::default());
    e.write_all(STR.as_ref()).unwrap();
    let enc = e.finish().unwrap();

    let client = reqwest::Client::new();
    let mut res = client.post(&srv.url("/"))
        .header(ContentEncoding(vec![Encoding::Deflate]))
        .body(enc.clone()).send().unwrap();
    let mut bytes = BytesMut::with_capacity(1024).writer();
    let _ = res.copy_to(&mut bytes);
    let bytes = bytes.into_inner();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_brotli_encoding() {
    let srv = test::TestServer::new(|app| app.handler(|req: HttpRequest| {
        req.body()
            .and_then(|bytes: Bytes| {
                Ok(httpcodes::HTTPOk
                   .build()
                   .content_encoding(headers::ContentEncoding::Identity)
                   .body(bytes))
            }).responder()}
    ));

    let mut e = BrotliEncoder::new(Vec::new(), 5);
    e.write_all(STR.as_ref()).unwrap();
    let enc = e.finish().unwrap();

    let client = reqwest::Client::new();
    let mut res = client.post(&srv.url("/"))
        .header(ContentEncoding(vec![Encoding::Brotli]))
        .body(enc.clone()).send().unwrap();
    let mut bytes = BytesMut::with_capacity(1024).writer();
    let _ = res.copy_to(&mut bytes);
    let bytes = bytes.into_inner();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_application() {
    let srv = test::TestServer::with_factory(
        || Application::new().resource("/", |r| r.h(httpcodes::HTTPOk)));
    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
}

struct MiddlewareTest {
    start: Arc<AtomicUsize>,
    response: Arc<AtomicUsize>,
    finish: Arc<AtomicUsize>,
}

impl<S> middleware::Middleware<S> for MiddlewareTest {
    fn start(&self, _: &mut HttpRequest<S>) -> Result<middleware::Started> {
        self.start.store(self.start.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
        Ok(middleware::Started::Done)
    }

    fn response(&self, _: &mut HttpRequest<S>, resp: HttpResponse) -> Result<middleware::Response> {
        self.response.store(self.response.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
        Ok(middleware::Response::Done(resp))
    }

    fn finish(&self, _: &mut HttpRequest<S>, _: &HttpResponse) -> middleware::Finished {
        self.finish.store(self.finish.load(Ordering::Relaxed) + 1, Ordering::Relaxed);
        middleware::Finished::Done
    }
}

#[test]
fn test_middlewares() {
    let num1 = Arc::new(AtomicUsize::new(0));
    let num2 = Arc::new(AtomicUsize::new(0));
    let num3 = Arc::new(AtomicUsize::new(0));

    let act_num1 = Arc::clone(&num1);
    let act_num2 = Arc::clone(&num2);
    let act_num3 = Arc::clone(&num3);

    let srv = test::TestServer::new(
        move |app| app.middleware(MiddlewareTest{start: Arc::clone(&act_num1),
                                                 response: Arc::clone(&act_num2),
                                                 finish: Arc::clone(&act_num3)})
            .handler(httpcodes::HTTPOk)
    );

    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
    assert_eq!(num1.load(Ordering::Relaxed), 1);
    assert_eq!(num2.load(Ordering::Relaxed), 1);
    assert_eq!(num3.load(Ordering::Relaxed), 1);
}

#[test]
fn test_resource_middlewares() {
    let num1 = Arc::new(AtomicUsize::new(0));
    let num2 = Arc::new(AtomicUsize::new(0));
    let num3 = Arc::new(AtomicUsize::new(0));

    let act_num1 = Arc::clone(&num1);
    let act_num2 = Arc::clone(&num2);
    let act_num3 = Arc::clone(&num3);

    let srv = test::TestServer::new(
        move |app| app.handler2(
            httpcodes::HTTPOk,
            MiddlewareTest{start: Arc::clone(&act_num1),
                           response: Arc::clone(&act_num2),
                           finish: Arc::clone(&act_num3)})
    );

    assert!(reqwest::get(&srv.url("/")).unwrap().status().is_success());
    assert_eq!(num1.load(Ordering::Relaxed), 1);
    assert_eq!(num2.load(Ordering::Relaxed), 1);
    // assert_eq!(num3.load(Ordering::Relaxed), 1);
}
<|endoftext|>


<commit_before>#[cfg(feature = "bigdecimal")]
mod bigdecimal {
    extern crate bigdecimal;
    extern crate num_bigint;
    extern crate num_integer;
    extern crate num_traits;

    use self::bigdecimal::BigDecimal;
    use self::num_bigint::{BigInt, BigUint, Sign};
    use self::num_integer::Integer;
    use self::num_traits::{Signed, ToPrimitive, Zero};
    use std::io::prelude::*;

    use deserialize::{self, FromSql};
    use pg::data_types::PgNumeric;
    use pg::Pg;
    use serialize::{self, Output, ToSql};
    use sql_types::Numeric;

    use std::convert::{TryFrom, TryInto};
    use std::error::Error;

    /// Iterator over the digits of a big uint in base 10k.
    /// The digits will be returned in little endian order.
    struct ToBase10000(Option<BigUint>);

    impl Iterator for ToBase10000 {
        type Item = i16;

        fn next(&mut self) -> Option<Self::Item> {
            self.0.take().map(|v| {
                let (div, rem) = v.div_rem(&BigUint::from(10_000u16));
                if !div.is_zero() {
                    self.0 = Some(div);
                }
                rem.to_i16().expect("10000 always fits in an i16")
            })
        }
    }

    impl<'a> TryFrom<&'a PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: &'a PgNumeric) -> deserialize::Result<Self> {
            let (sign, weight, scale, digits) = match *numeric {
                PgNumeric::Positive {
                    weight,
                    scale,
                    ref digits,
                } => (Sign::Plus, weight, scale, digits),
                PgNumeric::Negative {
                    weight,
                    scale,
                    ref digits,
                } => (Sign::Minus, weight, scale, digits),
                PgNumeric::NaN => {
                    return Err(Box::from("NaN is not (yet) supported in BigDecimal"))
                }
            };

            let mut result = BigUint::default();
            let count = digits.len() as i64;
            for digit in digits {
                result *= BigUint::from(10_000u64);
                result += BigUint::from(*digit as u64);
            }
            // First digit got factor 10_000^(digits.len() - 1), but should get 10_000^weight
            let correction_exp = 4 * (i64::from(weight) - count + 1);
            let result = BigDecimal::new(BigInt::from_biguint(sign, result), -correction_exp)
                .with_scale(i64::from(scale));
            Ok(result)
        }
    }

    impl TryFrom<PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: PgNumeric) -> deserialize::Result<Self> {
            (&numeric).try_into()
        }
    }

    impl<'a> From<&'a BigDecimal> for PgNumeric {
        // NOTE(clippy): No `std::ops::MulAssign` impl for `BigInt`
        // NOTE(clippy): Clippy suggests to replace the `.take_while(|i| i.is_zero())`
        // with `.take_while(Zero::is_zero)`, but that's a false positive.
        // The closure gets an `&&i16` due to autoderef `<i16 as Zero>::is_zero(&self) -> bool`
        // is called. There is no impl for `&i16` that would work with this closure.
        #[allow(clippy::assign_op_pattern, clippy::redundant_closure)]
        fn from(decimal: &'a BigDecimal) -> Self {
            let (mut integer, scale) = decimal.as_bigint_and_exponent();
            let scale = scale as u16;
            integer = integer.abs();

            // Ensure that the decimal will always lie on a digit boundary
            for _ in 0..(4 - scale % 4) {
                integer = integer * 10;
            }
            let integer = integer.to_biguint().expect("integer is always positive");

            let mut digits = ToBase10000(Some(integer)).collect::<Vec<_>>();
            digits.reverse();
            let digits_after_decimal = scale as u16 / 4 + 1;
            let weight = digits.len() as i16 - digits_after_decimal as i16 - 1;

            let unnecessary_zeroes = if weight >= 0 {
                digits
                    .iter()
                    .rev()
                    .take_while(|i| i.is_zero())
                    .count()
            } else {
                0
            };

            let relevant_digits = digits.len() - unnecessary_zeroes;
            digits.truncate(relevant_digits);

            match decimal.sign() {
                Sign::Plus => PgNumeric::Positive {
                    digits,
                    scale,
                    weight,
                },
                Sign::Minus => PgNumeric::Negative {
                    digits,
                    scale,
                    weight,
                },
                Sign::NoSign => PgNumeric::Positive {
                    digits: vec![0],
                    scale: 0,
                    weight: 0,
                },
            }
        }
    }

    impl From<BigDecimal> for PgNumeric {
        fn from(bigdecimal: BigDecimal) -> Self {
            (&bigdecimal).into()
        }
    }

    impl ToSql<Numeric, Pg> for BigDecimal {
        fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
            let numeric = PgNumeric::from(self);
            ToSql::<Numeric, Pg>::to_sql(&numeric, out)
        }
    }

    impl FromSql<Numeric, Pg> for BigDecimal {
        fn from_sql(numeric: Option<&[u8]>) -> deserialize::Result<Self> {
            PgNumeric::from_sql(numeric)?.try_into()
        }
    }

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

        #[test]
        fn bigdecimal_to_pgnumeric_converts_digits_to_base_10000() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![10],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_properly_adjusts_scale() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.0").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 2,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000.0001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 4,
                digits: vec![1, 0, 0, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("0.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: -1,
                scale: 1,
                digits: vec![1000],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_retains_sign() {
            let decimal = BigDecimal::from_str("123.456").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("-123.456").unwrap();
            let expected = PgNumeric::Negative {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        #[cfg(feature = "unstable")]
        fn pg_numeric_to_bigdecimal_works() {
            let expected = BigDecimal::from_str("123.456").unwrap();
            let pg_numeric = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);

            let expected = BigDecimal::from_str("-56.78").unwrap();
            let pg_numeric = PgNumeric::Negative {
                weight: 0,
                scale: 2,
                digits: vec![56, 7800],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);
        }
    }
}
<commit_msg>Cargo fmt<commit_after>#[cfg(feature = "bigdecimal")]
mod bigdecimal {
    extern crate bigdecimal;
    extern crate num_bigint;
    extern crate num_integer;
    extern crate num_traits;

    use self::bigdecimal::BigDecimal;
    use self::num_bigint::{BigInt, BigUint, Sign};
    use self::num_integer::Integer;
    use self::num_traits::{Signed, ToPrimitive, Zero};
    use std::io::prelude::*;

    use deserialize::{self, FromSql};
    use pg::data_types::PgNumeric;
    use pg::Pg;
    use serialize::{self, Output, ToSql};
    use sql_types::Numeric;

    use std::convert::{TryFrom, TryInto};
    use std::error::Error;

    /// Iterator over the digits of a big uint in base 10k.
    /// The digits will be returned in little endian order.
    struct ToBase10000(Option<BigUint>);

    impl Iterator for ToBase10000 {
        type Item = i16;

        fn next(&mut self) -> Option<Self::Item> {
            self.0.take().map(|v| {
                let (div, rem) = v.div_rem(&BigUint::from(10_000u16));
                if !div.is_zero() {
                    self.0 = Some(div);
                }
                rem.to_i16().expect("10000 always fits in an i16")
            })
        }
    }

    impl<'a> TryFrom<&'a PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: &'a PgNumeric) -> deserialize::Result<Self> {
            let (sign, weight, scale, digits) = match *numeric {
                PgNumeric::Positive {
                    weight,
                    scale,
                    ref digits,
                } => (Sign::Plus, weight, scale, digits),
                PgNumeric::Negative {
                    weight,
                    scale,
                    ref digits,
                } => (Sign::Minus, weight, scale, digits),
                PgNumeric::NaN => {
                    return Err(Box::from("NaN is not (yet) supported in BigDecimal"))
                }
            };

            let mut result = BigUint::default();
            let count = digits.len() as i64;
            for digit in digits {
                result *= BigUint::from(10_000u64);
                result += BigUint::from(*digit as u64);
            }
            // First digit got factor 10_000^(digits.len() - 1), but should get 10_000^weight
            let correction_exp = 4 * (i64::from(weight) - count + 1);
            let result = BigDecimal::new(BigInt::from_biguint(sign, result), -correction_exp)
                .with_scale(i64::from(scale));
            Ok(result)
        }
    }

    impl TryFrom<PgNumeric> for BigDecimal {
        type Error = Box<Error + Send + Sync>;

        fn try_from(numeric: PgNumeric) -> deserialize::Result<Self> {
            (&numeric).try_into()
        }
    }

    impl<'a> From<&'a BigDecimal> for PgNumeric {
        // NOTE(clippy): No `std::ops::MulAssign` impl for `BigInt`
        // NOTE(clippy): Clippy suggests to replace the `.take_while(|i| i.is_zero())`
        // with `.take_while(Zero::is_zero)`, but that's a false positive.
        // The closure gets an `&&i16` due to autoderef `<i16 as Zero>::is_zero(&self) -> bool`
        // is called. There is no impl for `&i16` that would work with this closure.
        #[allow(clippy::assign_op_pattern, clippy::redundant_closure)]
        fn from(decimal: &'a BigDecimal) -> Self {
            let (mut integer, scale) = decimal.as_bigint_and_exponent();
            let scale = scale as u16;
            integer = integer.abs();

            // Ensure that the decimal will always lie on a digit boundary
            for _ in 0..(4 - scale % 4) {
                integer = integer * 10;
            }
            let integer = integer.to_biguint().expect("integer is always positive");

            let mut digits = ToBase10000(Some(integer)).collect::<Vec<_>>();
            digits.reverse();
            let digits_after_decimal = scale as u16 / 4 + 1;
            let weight = digits.len() as i16 - digits_after_decimal as i16 - 1;

            let unnecessary_zeroes = if weight >= 0 {
                digits.iter().rev().take_while(|i| i.is_zero()).count()
            } else {
                0
            };

            let relevant_digits = digits.len() - unnecessary_zeroes;
            digits.truncate(relevant_digits);

            match decimal.sign() {
                Sign::Plus => PgNumeric::Positive {
                    digits,
                    scale,
                    weight,
                },
                Sign::Minus => PgNumeric::Negative {
                    digits,
                    scale,
                    weight,
                },
                Sign::NoSign => PgNumeric::Positive {
                    digits: vec![0],
                    scale: 0,
                    weight: 0,
                },
            }
        }
    }

    impl From<BigDecimal> for PgNumeric {
        fn from(bigdecimal: BigDecimal) -> Self {
            (&bigdecimal).into()
        }
    }

    impl ToSql<Numeric, Pg> for BigDecimal {
        fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
            let numeric = PgNumeric::from(self);
            ToSql::<Numeric, Pg>::to_sql(&numeric, out)
        }
    }

    impl FromSql<Numeric, Pg> for BigDecimal {
        fn from_sql(numeric: Option<&[u8]>) -> deserialize::Result<Self> {
            PgNumeric::from_sql(numeric)?.try_into()
        }
    }

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

        #[test]
        fn bigdecimal_to_pgnumeric_converts_digits_to_base_10000() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![10],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("10001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 1,
                scale: 0,
                digits: vec![1, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_properly_adjusts_scale() {
            let decimal = BigDecimal::from_str("1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 0,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.0").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 1,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("1.10").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 2,
                digits: vec![1, 1000],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("100000000.0001").unwrap();
            let expected = PgNumeric::Positive {
                weight: 2,
                scale: 4,
                digits: vec![1, 0, 0, 1],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("0.1").unwrap();
            let expected = PgNumeric::Positive {
                weight: -1,
                scale: 1,
                digits: vec![1000],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        fn bigdecimal_to_pg_numeric_retains_sign() {
            let decimal = BigDecimal::from_str("123.456").unwrap();
            let expected = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());

            let decimal = BigDecimal::from_str("-123.456").unwrap();
            let expected = PgNumeric::Negative {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            assert_eq!(expected, decimal.into());
        }

        #[test]
        #[cfg(feature = "unstable")]
        fn pg_numeric_to_bigdecimal_works() {
            let expected = BigDecimal::from_str("123.456").unwrap();
            let pg_numeric = PgNumeric::Positive {
                weight: 0,
                scale: 3,
                digits: vec![123, 4560],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);

            let expected = BigDecimal::from_str("-56.78").unwrap();
            let pg_numeric = PgNumeric::Negative {
                weight: 0,
                scale: 2,
                digits: vec![56, 7800],
            };
            let res: BigDecimal = pg_numeric.try_into().unwrap();
            assert_eq!(res, expected);
        }
    }
}
<|endoftext|>


<commit_before>use super::super::ScaleChangeArgs;
use super::media_query_handle::MediaQueryListHandle;

use std::{cell::RefCell, rc::Rc};
use wasm_bindgen::prelude::Closure;
use web_sys::MediaQueryListEvent;

pub struct ScaleChangeDetector(Rc<RefCell<ScaleChangeDetectorInternal>>);

impl ScaleChangeDetector {
    pub(crate) fn new<F>(handler: F) -> Self
    where
        F: 'static + FnMut(ScaleChangeArgs),
    {
        Self(ScaleChangeDetectorInternal::new(handler))
    }
}

/// This is a helper type to help manage the `MediaQueryList` used for detecting
/// changes of the `devicePixelRatio`.
struct ScaleChangeDetectorInternal {
    callback: Box<dyn FnMut(ScaleChangeArgs)>,
    mql: Option<MediaQueryListHandle>,
    last_scale: f64,
}

impl ScaleChangeDetectorInternal {
    fn new<F>(handler: F) -> Rc<RefCell<Self>>
    where
        F: 'static + FnMut(ScaleChangeArgs),
    {
        let current_scale = super::scale_factor();
        let new_self = Rc::new(RefCell::new(Self {
            callback: Box::new(handler),
            mql: None,
            last_scale: current_scale,
        }));

        let weak_self = Rc::downgrade(&new_self);
        let closure = Closure::wrap(Box::new(move |event: MediaQueryListEvent| {
            if let Some(rc_self) = weak_self.upgrade() {
                rc_self.borrow_mut().handler(event);
            }
        }) as Box<dyn FnMut(_)>);

        let mql = Self::create_mql(closure);
        {
            let mut borrowed_self = new_self.borrow_mut();
            borrowed_self.mql = mql;
        }
        new_self
    }

    fn create_mql(
        closure: Closure<dyn FnMut(MediaQueryListEvent)>,
    ) -> Option<MediaQueryListHandle> {
        let current_scale = super::scale_factor();
        // This media query initially matches the current `devicePixelRatio`.
        // We add 0.0001 to the lower and upper bounds such that it won't fail
        // due to floating point precision limitations.
        let media_query = format!(
            "(min-resolution: {:.4}dppx) and (max-resolution: {:.4}dppx)",
            current_scale - 0.0001,
            current_scale + 0.0001,
        );
        let mql = MediaQueryListHandle::new(&media_query, closure);
        if let Some(mql) = &mql {
            assert_eq!(mql.mql().matches(), true);
        }
        mql
    }

    fn handler(&mut self, event: MediaQueryListEvent) {
        assert_eq!(event.matches(), false);
        let mql = self
            .mql
            .take()
            .expect("DevicePixelRatioChangeDetector::mql should not be None");
        let closure = mql.remove();
        let new_scale = super::scale_factor();
        (self.callback)(ScaleChangeArgs {
            old_scale: self.last_scale,
            new_scale,
        });
        let new_mql = Self::create_mql(closure);
        self.mql = new_mql;
        self.last_scale = new_scale;
    }
}
<commit_msg>Fix failing assertion on start-up with Safari (#1736)<commit_after>use super::super::ScaleChangeArgs;
use super::media_query_handle::MediaQueryListHandle;

use std::{cell::RefCell, rc::Rc};
use wasm_bindgen::prelude::Closure;
use web_sys::MediaQueryListEvent;

pub struct ScaleChangeDetector(Rc<RefCell<ScaleChangeDetectorInternal>>);

impl ScaleChangeDetector {
    pub(crate) fn new<F>(handler: F) -> Self
    where
        F: 'static + FnMut(ScaleChangeArgs),
    {
        Self(ScaleChangeDetectorInternal::new(handler))
    }
}

/// This is a helper type to help manage the `MediaQueryList` used for detecting
/// changes of the `devicePixelRatio`.
struct ScaleChangeDetectorInternal {
    callback: Box<dyn FnMut(ScaleChangeArgs)>,
    mql: Option<MediaQueryListHandle>,
    last_scale: f64,
}

impl ScaleChangeDetectorInternal {
    fn new<F>(handler: F) -> Rc<RefCell<Self>>
    where
        F: 'static + FnMut(ScaleChangeArgs),
    {
        let current_scale = super::scale_factor();
        let new_self = Rc::new(RefCell::new(Self {
            callback: Box::new(handler),
            mql: None,
            last_scale: current_scale,
        }));

        let weak_self = Rc::downgrade(&new_self);
        let closure = Closure::wrap(Box::new(move |event: MediaQueryListEvent| {
            if let Some(rc_self) = weak_self.upgrade() {
                rc_self.borrow_mut().handler(event);
            }
        }) as Box<dyn FnMut(_)>);

        let mql = Self::create_mql(closure);
        {
            let mut borrowed_self = new_self.borrow_mut();
            borrowed_self.mql = mql;
        }
        new_self
    }

    fn create_mql(
        closure: Closure<dyn FnMut(MediaQueryListEvent)>,
    ) -> Option<MediaQueryListHandle> {
        let current_scale = super::scale_factor();
        // This media query initially matches the current `devicePixelRatio`.
        // We add 0.0001 to the lower and upper bounds such that it won't fail
        // due to floating point precision limitations.
        let media_query = format!(
            "(min-resolution: {min_scale:.4}dppx) and (max-resolution: {max_scale:.4}dppx),
             (-webkit-min-device-pixel-ratio: {min_scale:.4}) and (-webkit-max-device-pixel-ratio: {max_scale:.4})",
            min_scale = current_scale - 0.0001, max_scale= current_scale + 0.0001,
        );
        let mql = MediaQueryListHandle::new(&media_query, closure);
        if let Some(mql) = &mql {
            assert_eq!(mql.mql().matches(), true);
        }
        mql
    }

    fn handler(&mut self, event: MediaQueryListEvent) {
        assert_eq!(event.matches(), false);
        let mql = self
            .mql
            .take()
            .expect("DevicePixelRatioChangeDetector::mql should not be None");
        let closure = mql.remove();
        let new_scale = super::scale_factor();
        (self.callback)(ScaleChangeArgs {
            old_scale: self.last_scale,
            new_scale,
        });
        let new_mql = Self::create_mql(closure);
        self.mql = new_mql;
        self.last_scale = new_scale;
    }
}
<|endoftext|>


<commit_before>use std::mem;

use common::types::{Type, TypeId, TypeHandler};
use common::rows::{MiniPage};
use common::str::{StrSlice};
use rows::fixed_len::FMiniPage;

const BOOL_STR       : &'static str = "bool";
const INT1_STR       : &'static str = "int1";
const INT2_STR       : &'static str = "int2";
const INT4_STR       : &'static str = "int4";
const INT8_STR       : &'static str = "int8";
const FLOAT4_STR     : &'static str = "float4";
const FLOAT8_STR     : &'static str = "float8";
const NUMERIC_STR    : &'static str = "numeric";
const DATE_STR       : &'static str = "date";
const TIME_STR       : &'static str = "time";
const TIMEZ_STR      : &'static str = "time with timezone";
const TIMESTAMP_STR  : &'static str = "timestamp";
const TIMESTAMPZ_STR : &'static str = "timestamp with timezone";
const INTERVAL_STR   : &'static str = "interval";
const CHAR_STR       : &'static str = "char";
const BINARY_STR     : &'static str = "binary";
const CLOB_STR       : &'static str = "clob";
const BLOB_STR       : &'static str = "blob";

//pub const BOOL:       TypeId = TypeId {base: String::from(BOOL_STR)};
//pub const INT1:       TypeId = TypeId {base: INT1_STR.to_string()};
//pub const INT2:       TypeId = TypeId {base: INT2_STR.to_string()};
//pub const INT4:       TypeId = TypeId {base: INT4_STR.to_string()};
//pub const INT8:       TypeId = TypeId {base: INT8_STR.to_string()};
//pub const FLOAT4:     TypeId = TypeId {base: FLOAT4_STR.to_string()};
//pub const FLOAT8:     TypeId = TypeId {base: FLOAT8_STR.to_string()};
//pub const NUMERIC:    TypeId = TypeId {base: NUMERIC_STR.to_string()};
//pub const DATE:       TypeId = TypeId {base: DATE_STR.to_string()};
//pub const TIME:       TypeId = TypeId {base: TIME_STR.to_string()};
//pub const TIMEZ:      TypeId = TypeId {base: TIMEZ_STR.to_string()};
//pub const TIMESTAMP:  TypeId = TypeId {base: TIMESTAMP_STR.to_string()};
//pub const TIMESTAMPZ: TypeId = TypeId {base: TIMESTAMPZ_STR.to_string()};
//pub const INTERVAL:   TypeId = TypeId {base: INTERVAL_STR.to_string()};
//pub const CHAR:       TypeId = TypeId {base: CHAR_STR.to_string()};
//pub const BINARY:     TypeId = TypeId {base: BINARY_STR.to_string()};
//pub const CLOB:       TypeId = TypeId {base: CLOB_STR.to_string()};
//pub const BLOB:       TypeId = TypeId {base: BLOB_STR.to_string()};

#[allow(non_camel_case_types)]
pub type BOOL_T      = bool;
#[allow(non_camel_case_types)]
pub type INT1_T      = i8;
#[allow(non_camel_case_types)]
pub type INT2_T      = i16;
#[allow(non_camel_case_types)]
pub type INT4_T      = i32;
#[allow(non_camel_case_types)]
pub type INT8_T      = i64;
#[allow(non_camel_case_types)]
pub type FLOAT4_T    = f32;
#[allow(non_camel_case_types)]
pub type FLOAT8_T    = f64;
#[allow(non_camel_case_types)]
pub type DATE_T      = i32;
#[allow(non_camel_case_types)]
pub type TIME_T      = i64;
#[allow(non_camel_case_types)]
pub type TIMESTAMP_T = i64;
#[allow(non_camel_case_types)]
pub type TEXT_T      = StrSlice;

#[derive(Clone, PartialEq, Debug)]
pub struct Int4 {
  id: TypeId
}

impl Int4 {
  pub fn new() -> Int4 {
    Int4 {
      id: TypeId {
        base: String::from(INT4_STR)
      }
    }
  }
}

impl Type for Int4 {
  #[inline]
  fn id(&self) -> &TypeId { &self.id }
  #[inline]
  fn display_name(&self) -> &str { &self.id.base }
  #[inline]
  fn is_comparable(&self) -> bool { true }
  #[inline]
  fn is_orderable(&self) -> bool { true }
  #[inline]
  fn type_params(&self) -> Vec<&Type> { Vec::new() }
//  #[inline]
//  fn hash_fn(&self) -> Box<FnMut(&Vector, &mut [u32])>;
  #[inline]
  fn handler_factory (&self) -> Box<TypeHandler> {
    let f = || -> Box<MiniPage> {
          Box::new(FMiniPage::new(mem::size_of::<i32>()))
    };

    Box::new(
      TypeHandler {
        create_minipage_writer: Box::new(f)
      }
    )
  }
}

#[derive(Clone, PartialEq, Debug)]
pub struct Float4 {
  id: TypeId
}

impl Int4 {
  pub fn new() -> Int4 {
    Int4 {
      id: TypeId {
        base: String::from(FLOAT4_STR)
      }
    }
  }
}

impl Type for Float4 {
  #[inline]
  fn id(&self) -> &TypeId { &self.id }
  #[inline]
  fn display_name(&self) -> &str { &self.id.base }
  #[inline]
  fn is_comparable(&self) -> bool { true }
  #[inline]
  fn is_orderable(&self) -> bool { true }
  #[inline]
  fn type_params(&self) -> Vec<&Type> { Vec::new() }
//  #[inline]
//  fn hash_fn(&self) -> Box<FnMut(&Vector, &mut [u32])>;
  #[inline]
  fn handler_factory (&self) -> Box<TypeHandler> {
    let f = || -> Box<MiniPage> {
          Box::new(FMiniPage::new(mem::size_of::<f32>()))
    };

    Box::new(
      TypeHandler {
        create_minipage_writer: Box::new(f)
      }
    )
  }
}

#[test]
pub fn test_int4() {
  //let page_builder: Box<PageBuilder> = Box::new(DefaultPageBuilder);
//  let page = page_builder.create(&vec![
//    Box::new(Int4Type)
//  ]);
//  println!("{}", page.column_num());
}<commit_msg>Reformat the coding standard in sql/types.rs<commit_after>use std::mem;

use common::types::{Type, TypeId, TypeHandler};
use common::rows::{MiniPage};
use common::str::{StrSlice};
use rows::fixed_len::FMiniPage;

const BOOL_STR       : &'static str = "bool";
const INT1_STR       : &'static str = "int1";
const INT2_STR       : &'static str = "int2";
const INT4_STR       : &'static str = "int4";
const INT8_STR       : &'static str = "int8";
const FLOAT4_STR     : &'static str = "float4";
const FLOAT8_STR     : &'static str = "float8";
const NUMERIC_STR    : &'static str = "numeric";
const DATE_STR       : &'static str = "date";
const TIME_STR       : &'static str = "time";
const TIMEZ_STR      : &'static str = "time with timezone";
const TIMESTAMP_STR  : &'static str = "timestamp";
const TIMESTAMPZ_STR : &'static str = "timestamp with timezone";
const INTERVAL_STR   : &'static str = "interval";
const CHAR_STR       : &'static str = "char";
const BINARY_STR     : &'static str = "binary";
const CLOB_STR       : &'static str = "clob";
const BLOB_STR       : &'static str = "blob";

//pub const BOOL:       TypeId = TypeId {base: String::from(BOOL_STR)};
//pub const INT1:       TypeId = TypeId {base: INT1_STR.to_string()};
//pub const INT2:       TypeId = TypeId {base: INT2_STR.to_string()};
//pub const INT4:       TypeId = TypeId {base: INT4_STR.to_string()};
//pub const INT8:       TypeId = TypeId {base: INT8_STR.to_string()};
//pub const FLOAT4:     TypeId = TypeId {base: FLOAT4_STR.to_string()};
//pub const FLOAT8:     TypeId = TypeId {base: FLOAT8_STR.to_string()};
//pub const NUMERIC:    TypeId = TypeId {base: NUMERIC_STR.to_string()};
//pub const DATE:       TypeId = TypeId {base: DATE_STR.to_string()};
//pub const TIME:       TypeId = TypeId {base: TIME_STR.to_string()};
//pub const TIMEZ:      TypeId = TypeId {base: TIMEZ_STR.to_string()};
//pub const TIMESTAMP:  TypeId = TypeId {base: TIMESTAMP_STR.to_string()};
//pub const TIMESTAMPZ: TypeId = TypeId {base: TIMESTAMPZ_STR.to_string()};
//pub const INTERVAL:   TypeId = TypeId {base: INTERVAL_STR.to_string()};
//pub const CHAR:       TypeId = TypeId {base: CHAR_STR.to_string()};
//pub const BINARY:     TypeId = TypeId {base: BINARY_STR.to_string()};
//pub const CLOB:       TypeId = TypeId {base: CLOB_STR.to_string()};
//pub const BLOB:       TypeId = TypeId {base: BLOB_STR.to_string()};

#[allow(non_camel_case_types)]
pub type BOOL_T      = bool;
#[allow(non_camel_case_types)]
pub type INT1_T      = i8;
#[allow(non_camel_case_types)]
pub type INT2_T      = i16;
#[allow(non_camel_case_types)]
pub type INT4_T      = i32;
#[allow(non_camel_case_types)]
pub type INT8_T      = i64;
#[allow(non_camel_case_types)]
pub type FLOAT4_T    = f32;
#[allow(non_camel_case_types)]
pub type FLOAT8_T    = f64;
#[allow(non_camel_case_types)]
pub type DATE_T      = i32;
#[allow(non_camel_case_types)]
pub type TIME_T      = i64;
#[allow(non_camel_case_types)]
pub type TIMESTAMP_T = i64;
#[allow(non_camel_case_types)]
pub type TEXT_T      = StrSlice;

#[derive(Clone, PartialEq, Debug)]
pub struct Int4
{
  id: TypeId
}

impl Int4
{
  pub fn new() -> Self
  {
    Int4 {id: TypeId {base: String::from(INT4_STR)} }
  }
}

impl Type for Int4
{
  #[inline]
  fn id(&self) -> &TypeId { &self.id }
  #[inline]
  fn display_name(&self) -> &str { &self.id.base }
  #[inline]
  fn is_comparable(&self) -> bool { true }
  #[inline]
  fn is_orderable(&self) -> bool { true }
  #[inline]
  fn type_params(&self) -> Vec<&Type> { Vec::new() }
//  #[inline]
//  fn hash_fn(&self) -> Box<FnMut(&Vector, &mut [u32])>;
  #[inline]
  fn handler_factory (&self) -> Box<TypeHandler>
  {
    let f = || -> Box<MiniPage> {Box::new(FMiniPage::new(mem::size_of::<i32>()))};

    Box::new(TypeHandler {create_minipage_writer: Box::new(f)})
  }
}

#[derive(Clone, PartialEq, Debug)]
pub struct Float4
{
  id: TypeId
}

impl Int4
{
  pub fn new() -> Self {
    Int4 {id: TypeId {base: String::from(FLOAT4_STR)}}
  }
}

impl Type for Float4
{
  #[inline]
  fn id(&self) -> &TypeId { &self.id }
  #[inline]
  fn display_name(&self) -> &str { &self.id.base }
  #[inline]
  fn is_comparable(&self) -> bool { true }
  #[inline]
  fn is_orderable(&self) -> bool { true }
  #[inline]
  fn type_params(&self) -> Vec<&Type> { Vec::new() }
//  #[inline]
//  fn hash_fn(&self) -> Box<FnMut(&Vector, &mut [u32])>;
  #[inline]
  fn handler_factory (&self) -> Box<TypeHandler>
  {
    let f = || -> Box<MiniPage> {Box::new(FMiniPage::new(mem::size_of::<f32>()))};

    Box::new(TypeHandler {create_minipage_writer: Box::new(f)})
  }
}<|endoftext|>


<commit_before>use std::marker::PhantomData;

// @has useless_lifetime_bound/struct.Scope.html
// @!has - '//*[@class="rust struct"]' "'env: 'env"
pub struct Scope<'env> {
    _marker: PhantomData<&'env mut &'env ()>,
}
<commit_msg>Add test from #59033<commit_after>use std::marker::PhantomData;

// @has useless_lifetime_bound/struct.Scope.html
// @!has - '//*[@class="rust struct"]' "'env: 'env"
pub struct Scope<'env> {
    _marker: PhantomData<&'env mut &'env ()>,
}

// @has useless_lifetime_bound/struct.Scope.html
// @!has - '//*[@class="rust struct"]' "T: 'a + 'a"
pub struct SomeStruct<'a, T: 'a> {
    _marker: PhantomData<&'a T>,
}
<|endoftext|>


<commit_before><commit_msg>done but issue..<commit_after><|endoftext|>


<commit_before>#[macro_use]
extern crate abomonation;
extern crate timely;
extern crate differential_dataflow;
extern crate arrayvec;

use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::time::Instant;

use timely::dataflow::*;
use timely::dataflow::operators::*;
use timely::progress::timestamp::RootTimestamp;
use timely::progress::nested::product::Product;

use differential_dataflow::{Collection, AsCollection};

mod types;
mod queries;

use types::*;

fn main() {

    timely::execute_from_args(std::env::args().skip(4), |worker| {

        let index = worker.index();
        let peers = worker.peers();

        let prefix = ::std::env::args().nth(1).unwrap();;
        let logical_batch = ::std::env::args().nth(2).unwrap().parse::<usize>().unwrap();
        let physical_batch = ::std::env::args().nth(3).unwrap().parse::<usize>().unwrap();
        let query: usize = ::std::env::args().nth(4).unwrap().parse().unwrap();

        let (mut inputs, probes, used) = worker.dataflow::<usize,_,_>(move |scope| {

            // create new inputs to use in workers!
            let (cust_in, cust) = scope.new_input();
            let (line_in, line) = scope.new_input();
            let (nats_in, nats) = scope.new_input();
            let (ords_in, ords) = scope.new_input();
            let (part_in, part) = scope.new_input();
            let (psup_in, psup) = scope.new_input();
            let (regs_in, regs) = scope.new_input();
            let (supp_in, supp) = scope.new_input();

            let mut collections = Collections::new(
                cust.as_collection(),
                line.as_collection(),
                nats.as_collection(),
                ords.as_collection(),
                part.as_collection(),
                psup.as_collection(),
                regs.as_collection(),
                supp.as_collection(),
            );

            let mut probes = Vec::new();

            match query {
                1 => probes.push(queries::query01::query(&mut collections)),
                2 => probes.push(queries::query02::query(&mut collections)),
                3 => probes.push(queries::query03::query(&mut collections)),
                4 => probes.push(queries::query04::query(&mut collections)),
                5 => probes.push(queries::query05::query(&mut collections)),
                6 => probes.push(queries::query06::query(&mut collections)),
                7 => probes.push(queries::query07::query(&mut collections)),
                8 => probes.push(queries::query08::query(&mut collections)),
                9 => probes.push(queries::query09::query(&mut collections)),
                10 => probes.push(queries::query10::query(&mut collections)),
                11 => probes.push(queries::query11::query(&mut collections)),
                12 => probes.push(queries::query12::query(&mut collections)),
                13 => probes.push(queries::query13::query(&mut collections)),
                14 => probes.push(queries::query14::query(&mut collections)),
                15 => probes.push(queries::query15::query(&mut collections)),
                16 => probes.push(queries::query16::query(&mut collections)),
                17 => probes.push(queries::query17::query(&mut collections)),
                18 => probes.push(queries::query18::query(&mut collections)),
                19 => probes.push(queries::query19::query(&mut collections)),
                20 => probes.push(queries::query20::query(&mut collections)),
                21 => probes.push(queries::query21::query(&mut collections)),
                22 => probes.push(queries::query22::query(&mut collections)),
                _ => panic!("query: {:?} unimplemented", query),
            }

            // return the various input handles, and the list of probes.
            ((cust_in, line_in, nats_in, ords_in, part_in, psup_in, regs_in, supp_in), probes, collections.used)
        });

        // customer.tbl lineitem.tbl    nation.tbl  orders.tbl  part.tbl    partsupp.tbl    region.tbl  supplier.tbl
        let mut customers = if used[0] { load::<Customer>(prefix.as_str(), "customer.tbl", index, peers, logical_batch, physical_batch, 0) } else { Vec::new() };
        let mut lineitems = if used[1] { load::<LineItem>(prefix.as_str(), "lineitem.tbl", index, peers, logical_batch, physical_batch, 1) } else { Vec::new() };
        let mut nations = if used[2] { load::<Nation>(prefix.as_str(), "nation.tbl", index, peers, logical_batch, physical_batch, 2) } else { Vec::new() };
        let mut orders = if used[3] { load::<Order>(prefix.as_str(), "orders.tbl", index, peers, logical_batch, physical_batch, 3) } else { Vec::new() };
        let mut parts = if used[4] { load::<Part>(prefix.as_str(), "part.tbl", index, peers, logical_batch, physical_batch, 4) } else { Vec::new() };
        let mut partsupps = if used[5] { load::<PartSupp>(prefix.as_str(), "partsupp.tbl", index, peers, logical_batch, physical_batch, 5) } else { Vec::new() };
        let mut regions = if used[6] { load::<Region>(prefix.as_str(), "region.tbl", index, peers, logical_batch, physical_batch, 6) } else { Vec::new() };
        let mut suppliers = if used[7] { load::<Supplier>(prefix.as_str(), "supplier.tbl", index, peers, logical_batch, physical_batch, 7 ) } else { Vec::new() };

        let mut tuples = 0usize;
        tuples += customers.iter().map(|x| x.len()).sum();
        tuples += lineitems.iter().map(|x| x.len()).sum();
        tuples += nations.iter().map(|x| x.len()).sum();
        tuples += orders.iter().map(|x| x.len()).sum();
        tuples += parts.iter().map(|x| x.len()).sum();
        tuples += partsupps.iter().map(|x| x.len()).sum();
        tuples += regions.iter().map(|x| x.len()).sum();
        tuples += suppliers.iter().map(|x| x.len()).sum();

        let timer = Instant::now();
        let mut round = 0;
        while customers.len() > 0 || lineitems.len() > 0 || nations.len() > 0 || orders.len() > 0 || parts.len() > 0 || partsupps.len() > 0 || regions.len() > 0 || suppliers.len() > 0 {

            // introduce physical batch of data for each input with remaining data.
            if let Some(mut data) = customers.pop() { inputs.0.send_batch(&mut data); }
            if let Some(mut data) = lineitems.pop() { inputs.1.send_batch(&mut data); }
            if let Some(mut data) = nations.pop() { inputs.2.send_batch(&mut data); }
            if let Some(mut data) = orders.pop() { inputs.3.send_batch(&mut data); }
            if let Some(mut data) = parts.pop() { inputs.4.send_batch(&mut data); }
            if let Some(mut data) = partsupps.pop() { inputs.5.send_batch(&mut data); }
            if let Some(mut data) = regions.pop() { inputs.6.send_batch(&mut data); }
            if let Some(mut data) = suppliers.pop() { inputs.7.send_batch(&mut data); }

            // catch all inputs up to the same (next) round.
            let next_round = 8 * (round + 1) * physical_batch;
            inputs.0.advance_to(next_round);
            inputs.1.advance_to(next_round);
            inputs.2.advance_to(next_round);
            inputs.3.advance_to(next_round);
            inputs.4.advance_to(next_round);
            inputs.5.advance_to(next_round);
            inputs.6.advance_to(next_round);
            inputs.7.advance_to(next_round);

            let time = inputs.0.time();
            worker.step_while(|| probes.iter().all(|p| p.lt(&time)));
            round += 1;
        }

        let elapsed = timer.elapsed();
        let nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64;
        println!("elapsed: {:?}, tuples: {:?}, rate: {:?}", timer.elapsed(), tuples, (tuples as f64) / (nanos as f64 / 1000000000.0));

    }).unwrap();
}

pub struct Collections<G: Scope> {
    customers: Collection<G, Customer, isize>,
    lineitems: Collection<G, LineItem, isize>,
    nations: Collection<G, Nation, isize>,
    orders: Collection<G, Order, isize>,
    parts: Collection<G, Part, isize>,
    partsupps: Collection<G, PartSupp, isize>,
    regions: Collection<G, Region, isize>,
    suppliers: Collection<G, Supplier, isize>,
    used: [bool; 8],
}

impl<G: Scope> Collections<G> {
    fn new(
        customers: Collection<G, Customer, isize>,
        lineitems: Collection<G, LineItem, isize>,
        nations: Collection<G, Nation, isize>,
        orders: Collection<G, Order, isize>,
        parts: Collection<G, Part, isize>,
        partsupps: Collection<G, PartSupp, isize>,
        regions: Collection<G, Region, isize>,
        suppliers: Collection<G, Supplier, isize>,
    ) -> Self {

        Collections {
            customers: customers,
            lineitems: lineitems,
            nations: nations,
            orders: orders,
            parts: parts,
            partsupps: partsupps,
            regions: regions,
            suppliers: suppliers,
            used: [false; 8]
        }
    }

    fn customers(&mut self) -> &Collection<G, Customer, isize> { self.used[0] = true; &self.customers }
    fn lineitems(&mut self) -> &Collection<G, LineItem, isize> { self.used[1] = true; &self.lineitems }
    fn nations(&mut self) -> &Collection<G, Nation, isize> { self.used[2] = true; &self.nations }
    fn orders(&mut self) -> &Collection<G, Order, isize> { self.used[3] = true; &self.orders }
    fn parts(&mut self) -> &Collection<G, Part, isize> { self.used[4] = true; &self.parts }
    fn partsupps(&mut self) -> &Collection<G, PartSupp, isize> { self.used[5] = true; &self.partsupps }
    fn regions(&mut self) -> &Collection<G, Region, isize> { self.used[6] = true; &self.regions }
    fn suppliers(&mut self) -> &Collection<G, Supplier, isize> { self.used[7] = true; &self.suppliers }
}

// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet.
fn load<T>(prefix: &str, name: &str, index: usize, peers: usize, logical_batch: usize, physical_batch: usize, off: usize)
    -> Vec<Vec<(T, Product<RootTimestamp, usize>, isize)>>
where T: for<'a> From<&'a str> {

    let mut result = Vec::new();
    let mut buffer = Vec::new();

    let path = format!("{}{}", prefix, name);

    let items_file = File::open(&path).expect("didn't find items file");
    let mut items_reader =  BufReader::new(items_file);
    let mut count = 0;

    let mut line = String::new();

    while items_reader.read_line(&mut line).unwrap() > 0 {

        if count % peers == index {

            let logical = (8 * count / logical_batch) + off;
            let physical = logical / physical_batch;
            let round = physical / 8;

            while result.len() < round {
                result.push(buffer);
                buffer = Vec::with_capacity(2 + logical_batch * physical_batch / peers);
            }

            let item = T::from(line.as_str());
            buffer.push((item, RootTimestamp::new(logical), 1));
        }

        if count % 10000 == 0 {
            print!("\rreading records from {:?}: {:?}", name, count);
            ::std::io::stdout().flush().ok().expect("Could not flush stdout");
        }

        count += 1;

        line.clear();
    }
    println!("\rreading records from {:?}: {:?}", name, count);

    if buffer.len() > 0 {
        result.push(buffer);
    }

    result.reverse();
    result
}
<commit_msg>updated to track timely PartialOrder<commit_after>#[macro_use]
extern crate abomonation;
extern crate timely;
extern crate differential_dataflow;
extern crate arrayvec;

use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::time::Instant;

use timely::dataflow::*;
use timely::dataflow::operators::*;
use timely::progress::timestamp::RootTimestamp;
use timely::progress::nested::product::Product;

use differential_dataflow::{Collection, AsCollection};

mod types;
mod queries;

use types::*;

fn main() {

    timely::execute_from_args(std::env::args().skip(4), |worker| {

        let index = worker.index();
        let peers = worker.peers();

        let prefix = ::std::env::args().nth(1).unwrap();;
        let logical_batch = ::std::env::args().nth(2).unwrap().parse::<usize>().unwrap();
        let physical_batch = ::std::env::args().nth(3).unwrap().parse::<usize>().unwrap();
        let query: usize = ::std::env::args().nth(4).unwrap().parse().unwrap();

        let (mut inputs, probes, used) = worker.dataflow::<usize,_,_>(move |scope| {

            // create new inputs to use in workers!
            let (cust_in, cust) = scope.new_input();
            let (line_in, line) = scope.new_input();
            let (nats_in, nats) = scope.new_input();
            let (ords_in, ords) = scope.new_input();
            let (part_in, part) = scope.new_input();
            let (psup_in, psup) = scope.new_input();
            let (regs_in, regs) = scope.new_input();
            let (supp_in, supp) = scope.new_input();

            let mut collections = Collections::new(
                cust.as_collection(),
                line.as_collection(),
                nats.as_collection(),
                ords.as_collection(),
                part.as_collection(),
                psup.as_collection(),
                regs.as_collection(),
                supp.as_collection(),
            );

            let mut probes = Vec::new();

            match query {
                1 => probes.push(queries::query01::query(&mut collections)),
                2 => probes.push(queries::query02::query(&mut collections)),
                3 => probes.push(queries::query03::query(&mut collections)),
                4 => probes.push(queries::query04::query(&mut collections)),
                5 => probes.push(queries::query05::query(&mut collections)),
                6 => probes.push(queries::query06::query(&mut collections)),
                7 => probes.push(queries::query07::query(&mut collections)),
                8 => probes.push(queries::query08::query(&mut collections)),
                9 => probes.push(queries::query09::query(&mut collections)),
                10 => probes.push(queries::query10::query(&mut collections)),
                11 => probes.push(queries::query11::query(&mut collections)),
                12 => probes.push(queries::query12::query(&mut collections)),
                13 => probes.push(queries::query13::query(&mut collections)),
                14 => probes.push(queries::query14::query(&mut collections)),
                15 => probes.push(queries::query15::query(&mut collections)),
                16 => probes.push(queries::query16::query(&mut collections)),
                17 => probes.push(queries::query17::query(&mut collections)),
                18 => probes.push(queries::query18::query(&mut collections)),
                19 => probes.push(queries::query19::query(&mut collections)),
                20 => probes.push(queries::query20::query(&mut collections)),
                21 => probes.push(queries::query21::query(&mut collections)),
                22 => probes.push(queries::query22::query(&mut collections)),
                _ => panic!("query: {:?} unimplemented", query),
            }

            // return the various input handles, and the list of probes.
            ((cust_in, line_in, nats_in, ords_in, part_in, psup_in, regs_in, supp_in), probes, collections.used)
        });

        // customer.tbl lineitem.tbl    nation.tbl  orders.tbl  part.tbl    partsupp.tbl    region.tbl  supplier.tbl
        let mut customers = if used[0] { load::<Customer>(prefix.as_str(), "customer.tbl", index, peers, logical_batch, physical_batch, 0) } else { Vec::new() };
        let mut lineitems = if used[1] { load::<LineItem>(prefix.as_str(), "lineitem.tbl", index, peers, logical_batch, physical_batch, 1) } else { Vec::new() };
        let mut nations = if used[2] { load::<Nation>(prefix.as_str(), "nation.tbl", index, peers, logical_batch, physical_batch, 2) } else { Vec::new() };
        let mut orders = if used[3] { load::<Order>(prefix.as_str(), "orders.tbl", index, peers, logical_batch, physical_batch, 3) } else { Vec::new() };
        let mut parts = if used[4] { load::<Part>(prefix.as_str(), "part.tbl", index, peers, logical_batch, physical_batch, 4) } else { Vec::new() };
        let mut partsupps = if used[5] { load::<PartSupp>(prefix.as_str(), "partsupp.tbl", index, peers, logical_batch, physical_batch, 5) } else { Vec::new() };
        let mut regions = if used[6] { load::<Region>(prefix.as_str(), "region.tbl", index, peers, logical_batch, physical_batch, 6) } else { Vec::new() };
        let mut suppliers = if used[7] { load::<Supplier>(prefix.as_str(), "supplier.tbl", index, peers, logical_batch, physical_batch, 7 ) } else { Vec::new() };

        let mut tuples = 0usize;
        tuples += customers.iter().map(|x| x.len()).sum();
        tuples += lineitems.iter().map(|x| x.len()).sum();
        tuples += nations.iter().map(|x| x.len()).sum();
        tuples += orders.iter().map(|x| x.len()).sum();
        tuples += parts.iter().map(|x| x.len()).sum();
        tuples += partsupps.iter().map(|x| x.len()).sum();
        tuples += regions.iter().map(|x| x.len()).sum();
        tuples += suppliers.iter().map(|x| x.len()).sum();

        let timer = Instant::now();
        let mut round = 0;
        while customers.len() > 0 || lineitems.len() > 0 || nations.len() > 0 || orders.len() > 0 || parts.len() > 0 || partsupps.len() > 0 || regions.len() > 0 || suppliers.len() > 0 {

            // introduce physical batch of data for each input with remaining data.
            if let Some(mut data) = customers.pop() { inputs.0.send_batch(&mut data); }
            if let Some(mut data) = lineitems.pop() { inputs.1.send_batch(&mut data); }
            if let Some(mut data) = nations.pop() { inputs.2.send_batch(&mut data); }
            if let Some(mut data) = orders.pop() { inputs.3.send_batch(&mut data); }
            if let Some(mut data) = parts.pop() { inputs.4.send_batch(&mut data); }
            if let Some(mut data) = partsupps.pop() { inputs.5.send_batch(&mut data); }
            if let Some(mut data) = regions.pop() { inputs.6.send_batch(&mut data); }
            if let Some(mut data) = suppliers.pop() { inputs.7.send_batch(&mut data); }

            // catch all inputs up to the same (next) round.
            let next_round = 8 * (round + 1) * physical_batch;
            inputs.0.advance_to(next_round);
            inputs.1.advance_to(next_round);
            inputs.2.advance_to(next_round);
            inputs.3.advance_to(next_round);
            inputs.4.advance_to(next_round);
            inputs.5.advance_to(next_round);
            inputs.6.advance_to(next_round);
            inputs.7.advance_to(next_round);

            let time = inputs.0.time();
            worker.step_while(|| probes.iter().all(|p| p.less_than(&time)));
            round += 1;
        }

        let elapsed = timer.elapsed();
        let nanos = elapsed.as_secs() * 1000000000 + elapsed.subsec_nanos() as u64;
        println!("elapsed: {:?}, tuples: {:?}, rate: {:?}", timer.elapsed(), tuples, (tuples as f64) / (nanos as f64 / 1000000000.0));

    }).unwrap();
}

pub struct Collections<G: Scope> {
    customers: Collection<G, Customer, isize>,
    lineitems: Collection<G, LineItem, isize>,
    nations: Collection<G, Nation, isize>,
    orders: Collection<G, Order, isize>,
    parts: Collection<G, Part, isize>,
    partsupps: Collection<G, PartSupp, isize>,
    regions: Collection<G, Region, isize>,
    suppliers: Collection<G, Supplier, isize>,
    used: [bool; 8],
}

impl<G: Scope> Collections<G> {
    fn new(
        customers: Collection<G, Customer, isize>,
        lineitems: Collection<G, LineItem, isize>,
        nations: Collection<G, Nation, isize>,
        orders: Collection<G, Order, isize>,
        parts: Collection<G, Part, isize>,
        partsupps: Collection<G, PartSupp, isize>,
        regions: Collection<G, Region, isize>,
        suppliers: Collection<G, Supplier, isize>,
    ) -> Self {

        Collections {
            customers: customers,
            lineitems: lineitems,
            nations: nations,
            orders: orders,
            parts: parts,
            partsupps: partsupps,
            regions: regions,
            suppliers: suppliers,
            used: [false; 8]
        }
    }

    fn customers(&mut self) -> &Collection<G, Customer, isize> { self.used[0] = true; &self.customers }
    fn lineitems(&mut self) -> &Collection<G, LineItem, isize> { self.used[1] = true; &self.lineitems }
    fn nations(&mut self) -> &Collection<G, Nation, isize> { self.used[2] = true; &self.nations }
    fn orders(&mut self) -> &Collection<G, Order, isize> { self.used[3] = true; &self.orders }
    fn parts(&mut self) -> &Collection<G, Part, isize> { self.used[4] = true; &self.parts }
    fn partsupps(&mut self) -> &Collection<G, PartSupp, isize> { self.used[5] = true; &self.partsupps }
    fn regions(&mut self) -> &Collection<G, Region, isize> { self.used[6] = true; &self.regions }
    fn suppliers(&mut self) -> &Collection<G, Supplier, isize> { self.used[7] = true; &self.suppliers }
}

// Returns a sequence of physical batches of ready-to-go timestamped data. Not clear that `input` can exploit the pre-arrangement yet.
fn load<T>(prefix: &str, name: &str, index: usize, peers: usize, logical_batch: usize, physical_batch: usize, off: usize)
    -> Vec<Vec<(T, Product<RootTimestamp, usize>, isize)>>
where T: for<'a> From<&'a str> {

    let mut result = Vec::new();
    let mut buffer = Vec::new();

    let path = format!("{}{}", prefix, name);

    let items_file = File::open(&path).expect("didn't find items file");
    let mut items_reader =  BufReader::new(items_file);
    let mut count = 0;

    let mut line = String::new();

    while items_reader.read_line(&mut line).unwrap() > 0 {

        if count % peers == index {

            let logical = (8 * count / logical_batch) + off;
            let physical = logical / physical_batch;
            let round = physical / 8;

            while result.len() < round {
                result.push(buffer);
                buffer = Vec::with_capacity(2 + logical_batch * physical_batch / peers);
            }

            let item = T::from(line.as_str());
            buffer.push((item, RootTimestamp::new(logical), 1));
        }

        if count % 10000 == 0 {
            print!("\rreading records from {:?}: {:?}", name, count);
            ::std::io::stdout().flush().ok().expect("Could not flush stdout");
        }

        count += 1;

        line.clear();
    }
    println!("\rreading records from {:?}: {:?}", name, count);

    if buffer.len() > 0 {
        result.push(buffer);
    }

    result.reverse();
    result
}
<|endoftext|>


<commit_before>use futures::stable::block_on_stable;
use futures::prelude::*;

#[async]
fn foo() -> Result<i32, i32> {
    Ok(1)
}

#[async]
fn bar(x: &i32) -> Result<i32, i32> {
    Ok(*x)
}

#[async]
fn baz(x: i32) -> Result<i32, i32> {
    await!(bar(&x))
}

#[async_stream(item = u64)]
fn _stream1() -> Result<(), i32> {
    fn integer() -> u64 { 1 }
    let x = &integer();
    stream_yield!(0);
    stream_yield!(*x);
    Ok(())
}

#[async]
pub fn uses_async_for() -> Result<Vec<u64>, i32> {
    let mut v = vec![];
    #[async]
    for i in _stream1() {
        v.push(i);
    }
    Ok(v)
}

#[test]
fn main() {
    assert_eq!(block_on_stable(foo()), Ok(1));
    assert_eq!(block_on_stable(bar(&1)), Ok(1));
    assert_eq!(block_on_stable(baz(17)), Ok(17));
    assert_eq!(block_on_stable(uses_async_for()), Ok(vec![0, 1]));
}
<commit_msg>Add test of awaiting StableFuture from an async_move function<commit_after>use futures::stable::{block_on_stable, StableFuture};
use futures::prelude::*;

#[async]
fn foo() -> Result<i32, i32> {
    Ok(1)
}

#[async]
fn bar(x: &i32) -> Result<i32, i32> {
    Ok(*x)
}

#[async]
fn baz(x: i32) -> Result<i32, i32> {
    await!(bar(&x))
}

#[async_move]
fn qux(x: i32) -> Result<i32, i32> {
    await!(baz(x).pin())
}

#[async_stream(item = u64)]
fn _stream1() -> Result<(), i32> {
    fn integer() -> u64 { 1 }
    let x = &integer();
    stream_yield!(0);
    stream_yield!(*x);
    Ok(())
}

#[async]
pub fn uses_async_for() -> Result<Vec<u64>, i32> {
    let mut v = vec![];
    #[async]
    for i in _stream1() {
        v.push(i);
    }
    Ok(v)
}

#[test]
fn main() {
    assert_eq!(block_on_stable(foo()), Ok(1));
    assert_eq!(block_on_stable(bar(&1)), Ok(1));
    assert_eq!(block_on_stable(baz(17)), Ok(17));
    assert_eq!(block_on_stable(qux(17)), Ok(17));
    assert_eq!(block_on_stable(uses_async_for()), Ok(vec![0, 1]));
}
<|endoftext|>


<commit_before>// compile-flags: -Zunleash-the-miri-inside-of-you
#![feature(thread_local)]
#![allow(const_err)]

use std::thread;

#[thread_local]
static A: u8 = 0;

// Make sure we catch executing inline assembly.
static TEST_BAD: () = {
    unsafe { let _val = A; }
    //~^ ERROR could not evaluate static initializer
    //~| NOTE cannot access thread local static
};

fn main() {}
<commit_msg>Fix comment<commit_after>// compile-flags: -Zunleash-the-miri-inside-of-you
#![feature(thread_local)]
#![allow(const_err)]

use std::thread;

#[thread_local]
static A: u8 = 0;

// Make sure we catch accessing thread-local storage.
static TEST_BAD: () = {
    unsafe { let _val = A; }
    //~^ ERROR could not evaluate static initializer
    //~| NOTE cannot access thread local static
};

fn main() {}
<|endoftext|>