<commit_before>#![allow(deprecated)]
extern crate actix;
extern crate actix_web;
extern crate bytes;
extern crate flate2;
extern crate futures;
extern crate rand;
#[cfg(all(unix, feature = "uds"))]
extern crate tokio_uds;

use std::io::Read;

use bytes::Bytes;
use flate2::read::GzDecoder;
use futures::stream::once;
use futures::Future;
use rand::Rng;

use actix_web::*;

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 \
                   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 \
                   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 \
                   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 \
                   Hello World Hello World Hello World Hello World Hello World";

#[test]
fn test_simple() {
    let mut srv =
        test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));

    let request = srv.get().header("x-test", "111").finish().unwrap();
    let repr = format!("{:?}", request);
    assert!(repr.contains("ClientRequest"));
    assert!(repr.contains("x-test"));

    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));

    let request = srv.post().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_with_query_parameter() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| match req.query().get("qp") {
            Some(_) => HttpResponse::Ok().finish(),
            None => HttpResponse::BadRequest().finish(),
        })
    });

    let request = srv.get().uri(srv.url("/?qp=5").as_str()).finish().unwrap();

    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());
}

#[test]
fn test_no_decompress() {
    let mut srv =
        test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));

    let request = srv.get().disable_decompress().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();

    let mut e = GzDecoder::new(&bytes[..]);
    let mut dec = Vec::new();
    e.read_to_end(&mut dec).unwrap();
    assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));

    // POST
    let request = srv.post().disable_decompress().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();

    let bytes = srv.execute(response.body()).unwrap();
    let mut e = GzDecoder::new(&bytes[..]);
    let mut dec = Vec::new();
    e.read_to_end(&mut dec).unwrap();
    assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_client_gzip_encoding() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Deflate)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Gzip)
        .body(STR)
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_client_gzip_encoding_large() {
    let data = STR.repeat(10);

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Deflate)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Gzip)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from(data));
}

#[test]
fn test_client_gzip_encoding_large_random() {
    let data = rand::thread_rng()
        .gen_ascii_chars()
        .take(100_000)
        .collect::<String>();

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Deflate)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Gzip)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from(data));
}

#[cfg(all(unix, feature = "uds"))]
#[test]
fn test_compatible_with_unix_socket_stream() {
    let (stream, _) = tokio_uds::UnixStream::pair().unwrap();
    let _ = client::Connection::from_stream(stream);
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_brotli_encoding() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Gzip)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .client(http::Method::POST, "/")
        .content_encoding(http::ContentEncoding::Br)
        .body(STR)
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_brotli_encoding_large_random() {
    let data = rand::thread_rng()
        .gen_ascii_chars()
        .take(70_000)
        .collect::<String>();

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(move |bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Gzip)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .client(http::Method::POST, "/")
        .content_encoding(http::ContentEncoding::Br)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes.len(), data.len());
    assert_eq!(bytes, Bytes::from(data));
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_deflate_encoding() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Br)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Deflate)
        .body(STR)
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_deflate_encoding_large_random() {
    let data = rand::thread_rng()
        .gen_ascii_chars()
        .take(70_000)
        .collect::<String>();

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Br)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Deflate)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from(data));
}

#[test]
fn test_client_streaming_explicit() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .map_err(Error::from)
                .and_then(|body| {
                    Ok(HttpResponse::Ok()
                        .chunked()
                        .content_encoding(http::ContentEncoding::Identity)
                        .body(body))
                }).responder()
        })
    });

    let body = once(Ok(Bytes::from_static(STR.as_ref())));

    let request = srv.get().body(Body::Streaming(Box::new(body))).unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_body_streaming_implicit() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|_| {
            let body = once(Ok(Bytes::from_static(STR.as_ref())));
            HttpResponse::Ok()
                .content_encoding(http::ContentEncoding::Gzip)
                .body(Body::Streaming(Box::new(body)))
        })
    });

    let request = srv.get().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_client_cookie_handling() {
    use actix_web::http::Cookie;
    fn err() -> Error {
        use std::io::{Error as IoError, ErrorKind};
        // stub some generic error
        Error::from(IoError::from(ErrorKind::NotFound))
    }
    let cookie1 = Cookie::build("cookie1", "value1").finish();
    let cookie2 = Cookie::build("cookie2", "value2")
        .domain("www.example.org")
        .path("/")
        .secure(true)
        .http_only(true)
        .finish();
    // Q: are all these clones really necessary? A: Yes, possibly
    let cookie1b = cookie1.clone();
    let cookie2b = cookie2.clone();
    let mut srv = test::TestServer::new(move |app| {
        let cookie1 = cookie1b.clone();
        let cookie2 = cookie2b.clone();
        app.handler(move |req: &HttpRequest| {
            // Check cookies were sent correctly
            req.cookie("cookie1").ok_or_else(err)
                    .and_then(|c1| if c1.value() == "value1" {
                        Ok(())
                    } else {
                        Err(err())
                    })
                    .and_then(|()| req.cookie("cookie2").ok_or_else(err))
                    .and_then(|c2| if c2.value() == "value2" {
                        Ok(())
                    } else {
                        Err(err())
                    })
                    // Send some cookies back
                    .map(|_| HttpResponse::Ok()
                         .cookie(cookie1.clone())
                         .cookie(cookie2.clone())
                         .finish()
                    )
        })
    });

    let request = srv
        .get()
        .cookie(cookie1.clone())
        .cookie(cookie2.clone())
        .finish()
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());
    let c1 = response.cookie("cookie1").expect("Missing cookie1");
    assert_eq!(c1, cookie1);
    let c2 = response.cookie("cookie2").expect("Missing cookie2");
    assert_eq!(c2, cookie2);
}

#[test]
fn test_default_headers() {
    let srv = test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));

    let request = srv.get().finish().unwrap();
    let repr = format!("{:?}", request);
    assert!(repr.contains("\"accept-encoding\": \"gzip, deflate\""));
    assert!(repr.contains(concat!(
        "\"user-agent\": \"actix-web/",
        env!("CARGO_PKG_VERSION"),
        "\""
    )));

    let request_override = srv
        .get()
        .header("User-Agent", "test")
        .header("Accept-Encoding", "over_test")
        .finish()
        .unwrap();
    let repr_override = format!("{:?}", request_override);
    assert!(repr_override.contains("\"user-agent\": \"test\""));
    assert!(repr_override.contains("\"accept-encoding\": \"over_test\""));
    assert!(!repr_override.contains("\"accept-encoding\": \"gzip, deflate\""));
    assert!(!repr_override.contains(concat!(
        "\"user-agent\": \"Actix-web/",
        env!("CARGO_PKG_VERSION"),
        "\""
    )));
}
<commit_msg>Add client test for 'Connection: close' as reported in issue #495<commit_after>#![allow(deprecated)]
extern crate actix;
extern crate actix_web;
extern crate bytes;
extern crate flate2;
extern crate futures;
extern crate rand;
#[cfg(all(unix, feature = "uds"))]
extern crate tokio_uds;

use std::io::Read;

use bytes::Bytes;
use flate2::read::GzDecoder;
use futures::stream::once;
use futures::Future;
use rand::Rng;

use actix_web::*;

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 \
                   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 \
                   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 \
                   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 \
                   Hello World Hello World Hello World Hello World Hello World";

#[test]
fn test_simple() {
    let mut srv =
        test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));

    let request = srv.get().header("x-test", "111").finish().unwrap();
    let repr = format!("{:?}", request);
    assert!(repr.contains("ClientRequest"));
    assert!(repr.contains("x-test"));

    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));

    let request = srv.post().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_connection_close() {
    let mut srv =
        test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));

    let request = srv.get().header("Connection", "close").finish().unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());
}

#[test]
fn test_with_query_parameter() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| match req.query().get("qp") {
            Some(_) => HttpResponse::Ok().finish(),
            None => HttpResponse::BadRequest().finish(),
        })
    });

    let request = srv.get().uri(srv.url("/?qp=5").as_str()).finish().unwrap();

    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());
}

#[test]
fn test_no_decompress() {
    let mut srv =
        test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));

    let request = srv.get().disable_decompress().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();

    let mut e = GzDecoder::new(&bytes[..]);
    let mut dec = Vec::new();
    e.read_to_end(&mut dec).unwrap();
    assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));

    // POST
    let request = srv.post().disable_decompress().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();

    let bytes = srv.execute(response.body()).unwrap();
    let mut e = GzDecoder::new(&bytes[..]);
    let mut dec = Vec::new();
    e.read_to_end(&mut dec).unwrap();
    assert_eq!(Bytes::from(dec), Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_client_gzip_encoding() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Deflate)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Gzip)
        .body(STR)
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_client_gzip_encoding_large() {
    let data = STR.repeat(10);

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Deflate)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Gzip)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from(data));
}

#[test]
fn test_client_gzip_encoding_large_random() {
    let data = rand::thread_rng()
        .gen_ascii_chars()
        .take(100_000)
        .collect::<String>();

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Deflate)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Gzip)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from(data));
}

#[cfg(all(unix, feature = "uds"))]
#[test]
fn test_compatible_with_unix_socket_stream() {
    let (stream, _) = tokio_uds::UnixStream::pair().unwrap();
    let _ = client::Connection::from_stream(stream);
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_brotli_encoding() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Gzip)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .client(http::Method::POST, "/")
        .content_encoding(http::ContentEncoding::Br)
        .body(STR)
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_brotli_encoding_large_random() {
    let data = rand::thread_rng()
        .gen_ascii_chars()
        .take(70_000)
        .collect::<String>();

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(move |bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Gzip)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .client(http::Method::POST, "/")
        .content_encoding(http::ContentEncoding::Br)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes.len(), data.len());
    assert_eq!(bytes, Bytes::from(data));
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_deflate_encoding() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Br)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Deflate)
        .body(STR)
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[cfg(feature = "brotli")]
#[test]
fn test_client_deflate_encoding_large_random() {
    let data = rand::thread_rng()
        .gen_ascii_chars()
        .take(70_000)
        .collect::<String>();

    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .and_then(|bytes: Bytes| {
                    Ok(HttpResponse::Ok()
                        .content_encoding(http::ContentEncoding::Br)
                        .body(bytes))
                }).responder()
        })
    });

    // client request
    let request = srv
        .post()
        .content_encoding(http::ContentEncoding::Deflate)
        .body(data.clone())
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from(data));
}

#[test]
fn test_client_streaming_explicit() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|req: &HttpRequest| {
            req.body()
                .map_err(Error::from)
                .and_then(|body| {
                    Ok(HttpResponse::Ok()
                        .chunked()
                        .content_encoding(http::ContentEncoding::Identity)
                        .body(body))
                }).responder()
        })
    });

    let body = once(Ok(Bytes::from_static(STR.as_ref())));

    let request = srv.get().body(Body::Streaming(Box::new(body))).unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_body_streaming_implicit() {
    let mut srv = test::TestServer::new(|app| {
        app.handler(|_| {
            let body = once(Ok(Bytes::from_static(STR.as_ref())));
            HttpResponse::Ok()
                .content_encoding(http::ContentEncoding::Gzip)
                .body(Body::Streaming(Box::new(body)))
        })
    });

    let request = srv.get().finish().unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());

    // read response
    let bytes = srv.execute(response.body()).unwrap();
    assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}

#[test]
fn test_client_cookie_handling() {
    use actix_web::http::Cookie;
    fn err() -> Error {
        use std::io::{Error as IoError, ErrorKind};
        // stub some generic error
        Error::from(IoError::from(ErrorKind::NotFound))
    }
    let cookie1 = Cookie::build("cookie1", "value1").finish();
    let cookie2 = Cookie::build("cookie2", "value2")
        .domain("www.example.org")
        .path("/")
        .secure(true)
        .http_only(true)
        .finish();
    // Q: are all these clones really necessary? A: Yes, possibly
    let cookie1b = cookie1.clone();
    let cookie2b = cookie2.clone();
    let mut srv = test::TestServer::new(move |app| {
        let cookie1 = cookie1b.clone();
        let cookie2 = cookie2b.clone();
        app.handler(move |req: &HttpRequest| {
            // Check cookies were sent correctly
            req.cookie("cookie1").ok_or_else(err)
                    .and_then(|c1| if c1.value() == "value1" {
                        Ok(())
                    } else {
                        Err(err())
                    })
                    .and_then(|()| req.cookie("cookie2").ok_or_else(err))
                    .and_then(|c2| if c2.value() == "value2" {
                        Ok(())
                    } else {
                        Err(err())
                    })
                    // Send some cookies back
                    .map(|_| HttpResponse::Ok()
                         .cookie(cookie1.clone())
                         .cookie(cookie2.clone())
                         .finish()
                    )
        })
    });

    let request = srv
        .get()
        .cookie(cookie1.clone())
        .cookie(cookie2.clone())
        .finish()
        .unwrap();
    let response = srv.execute(request.send()).unwrap();
    assert!(response.status().is_success());
    let c1 = response.cookie("cookie1").expect("Missing cookie1");
    assert_eq!(c1, cookie1);
    let c2 = response.cookie("cookie2").expect("Missing cookie2");
    assert_eq!(c2, cookie2);
}

#[test]
fn test_default_headers() {
    let srv = test::TestServer::new(|app| app.handler(|_| HttpResponse::Ok().body(STR)));

    let request = srv.get().finish().unwrap();
    let repr = format!("{:?}", request);
    assert!(repr.contains("\"accept-encoding\": \"gzip, deflate\""));
    assert!(repr.contains(concat!(
        "\"user-agent\": \"actix-web/",
        env!("CARGO_PKG_VERSION"),
        "\""
    )));

    let request_override = srv
        .get()
        .header("User-Agent", "test")
        .header("Accept-Encoding", "over_test")
        .finish()
        .unwrap();
    let repr_override = format!("{:?}", request_override);
    assert!(repr_override.contains("\"user-agent\": \"test\""));
    assert!(repr_override.contains("\"accept-encoding\": \"over_test\""));
    assert!(!repr_override.contains("\"accept-encoding\": \"gzip, deflate\""));
    assert!(!repr_override.contains(concat!(
        "\"user-agent\": \"Actix-web/",
        env!("CARGO_PKG_VERSION"),
        "\""
    )));
}
<|endoftext|>


<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright 2014 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

extern crate claxon;
extern crate hound;

use std::fs;
use std::io;
use std::path;

fn run_metaflac(fname: &path::Path) -> String {
    use std::process::Command;

    // Run metaflac on the specified file and print all streaminfo data.
    let output = Command::new("metaflac")
                     .arg("--show-min-blocksize")
                     .arg("--show-max-blocksize")
                     .arg("--show-min-framesize")
                     .arg("--show-max-framesize")
                     .arg("--show-sample-rate")
                     .arg("--show-channels")
                     .arg("--show-bps")
                     .arg("--show-total-samples")
                     .arg("--show-md5sum")
                     .arg(fname.to_str().expect("unsupported filename"))
                     .output()
                     .expect("failed to run metaflac");
    String::from_utf8(output.stdout).expect("metaflac wrote invalid UTF-8")
}

fn decode_file(fname: &path::Path) {
    use std::process::Command;

    // Run the the reference flac decoder on the file.
    let success = Command::new("flac")
                      .arg("--decode")
                      .arg(fname.to_str().expect("unsupported filename"))
                      .status()
                      .expect("failed to run flac")
                      .success();
    assert!(success);
}

fn print_hex(seq: &[u8]) -> String {
    let vec: Vec<String> = seq.iter().map(|x| format!("{:0>2x}", *x)).collect();
    vec.concat()
}

fn read_streaminfo(fname: &path::Path) -> String {
    // Use a buffered reader, this speeds up the test by 120%.
    let file = fs::File::open(fname).unwrap();
    let reader = io::BufReader::new(file);
    let stream = claxon::FlacReader::new(reader).unwrap();
    let streaminfo = stream.streaminfo();

    // Format the streaminfo in the same way that metaflac prints it.
    format!("{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
            streaminfo.min_block_size,
            streaminfo.max_block_size,
            streaminfo.min_frame_size.unwrap_or(0),
            streaminfo.max_frame_size.unwrap_or(0),
            streaminfo.sample_rate,
            streaminfo.channels,
            streaminfo.bits_per_sample,
            streaminfo.samples.unwrap_or(0),
            print_hex(&streaminfo.md5sum)) // TODO implement LowerHex for &[u8] and submit a PR.
}

fn compare_metaflac(fname: &path::Path) {
    let metaflac = run_metaflac(fname);
    let streaminfo = read_streaminfo(fname);
    let mut mf_lines = metaflac.lines();
    let mut si_lines = streaminfo.lines();
    while let (Some(mf), Some(si)) = (mf_lines.next(), si_lines.next()) {
        if mf != si {
            println!("metaflac\n--------\n{}", metaflac);
            println!("streaminfo\n----------\n{}", streaminfo);
            panic!("metaflac disagrees on parsed streaminfo");
        }
    }
}

fn compare_decoded_stream(fname: &path::Path) {
    let ref_fname = fname.with_extension("wav");
    if !ref_fname.exists() {
        // TODO: actually, we might only want to run the test for files that
        // do exist already. It is fine to run streaminfo or decode-only tests
        // on thousands of files, but decoding thousands of files to wav before
        // running the tests will take a lot of space. For now, while the
        // number of samples is closer to 10 than to 100, this is fine.
        decode_file(fname);
    }

    // If the reference file does exist after decoding, we can compare it to
    // how Claxon decodes it, sample by sample.
    if ref_fname.exists() {
        let mut ref_wav_reader = hound::WavReader::open(ref_fname).unwrap();

        let try_file = fs::File::open(fname).unwrap();
        let try_buf_reader = io::BufReader::new(try_file);
        let mut try_flac_reader = claxon::FlacReader::new(try_buf_reader).unwrap();

        // The streaminfo test will ensure that things like bit depth and
        // sample rate match, only the actual samples are compared here.

        let mut ref_samples = ref_wav_reader.samples::<i32>();

        let samples = try_flac_reader.streaminfo().samples.unwrap();
        let n_channels = try_flac_reader.streaminfo().channels;
        let mut blocks = try_flac_reader.blocks::<i32>();
        let mut sample = 0u64;
        let mut b = 0u64;
        let mut buffer = Vec::new();

        while sample < samples {
            let block = blocks.read_next_or_eof(buffer).unwrap().unwrap();
            {
                let mut channels: Vec<_> = (0..n_channels)
                                               .map(|i| block.channel(i).iter().cloned())
                                               .collect();
                for i in 0..block.len() {
                    for ch in 0..n_channels as usize {
                        let ref_sample = ref_samples.next().map(|r| r.ok().unwrap());
                        let try_sample = channels[ch].next();
                        if ref_sample != try_sample {
                            println!("disagreement at sample {} of block {} in channel {}: \
                                      reference is {} but decoded is {}",
                                     i,
                                     b,
                                     ch,
                                     ref_sample.unwrap(),
                                     try_sample.unwrap());
                            panic!("decoding differs from reference decoder");
                        }
                    }
                }
                sample = sample + block.len() as u64;
            }
            b = b + 1;
            buffer = block.into_buffer();
        }
    }
}

// Hard-coded tests for the test samples added py populate.sh.
// This allows us to run these tests in parallel and follow progress without
// enabling --nocapture.

#[test]
fn verify_streaminfo_p0() {
    compare_metaflac(path::Path::new("testsamples/p0.flac"));
}

#[test]
fn verify_streaminfo_p1() {
    compare_metaflac(path::Path::new("testsamples/p1.flac"));
}

#[test]
fn verify_streaminfo_p2() {
    compare_metaflac(path::Path::new("testsamples/p2.flac"));
}

#[test]
fn verify_streaminfo_p3() {
    compare_metaflac(path::Path::new("testsamples/p3.flac"));
}

#[test]
fn verify_streaminfo_p4() {
    compare_metaflac(path::Path::new("testsamples/p4.flac"));
}

#[test]
fn verify_decoded_stream_p0() {
    compare_decoded_stream(path::Path::new("testsamples/p0.flac"));
}

#[test]
fn verify_decoded_stream_p1() {
    compare_decoded_stream(path::Path::new("testsamples/p1.flac"));
}

#[test]
fn verify_decoded_stream_p2() {
    compare_decoded_stream(path::Path::new("testsamples/p2.flac"));
}

#[test]
fn verify_decoded_stream_p3() {
    compare_decoded_stream(path::Path::new("testsamples/p3.flac"));
}

#[test]
fn verify_decoded_stream_p4() {
    compare_decoded_stream(path::Path::new("testsamples/p4.flac"));
}
<commit_msg>silence flac when decoding test samples<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright 2014 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

extern crate claxon;
extern crate hound;

use std::fs;
use std::io;
use std::path;

fn run_metaflac(fname: &path::Path) -> String {
    use std::process::Command;

    // Run metaflac on the specified file and print all streaminfo data.
    let output = Command::new("metaflac")
                     .arg("--show-min-blocksize")
                     .arg("--show-max-blocksize")
                     .arg("--show-min-framesize")
                     .arg("--show-max-framesize")
                     .arg("--show-sample-rate")
                     .arg("--show-channels")
                     .arg("--show-bps")
                     .arg("--show-total-samples")
                     .arg("--show-md5sum")
                     .arg(fname.to_str().expect("unsupported filename"))
                     .output()
                     .expect("failed to run metaflac");
    String::from_utf8(output.stdout).expect("metaflac wrote invalid UTF-8")
}

fn decode_file(fname: &path::Path) {
    use std::process::Command;

    // Run the the reference flac decoder on the file.
    let success = Command::new("flac")
                      .arg("--decode")
                      .arg("--silent")
                      .arg(fname.to_str().expect("unsupported filename"))
                      .status()
                      .expect("failed to run flac")
                      .success();
    assert!(success);
}

fn print_hex(seq: &[u8]) -> String {
    let vec: Vec<String> = seq.iter().map(|x| format!("{:0>2x}", *x)).collect();
    vec.concat()
}

fn read_streaminfo(fname: &path::Path) -> String {
    // Use a buffered reader, this speeds up the test by 120%.
    let file = fs::File::open(fname).unwrap();
    let reader = io::BufReader::new(file);
    let stream = claxon::FlacReader::new(reader).unwrap();
    let streaminfo = stream.streaminfo();

    // Format the streaminfo in the same way that metaflac prints it.
    format!("{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
            streaminfo.min_block_size,
            streaminfo.max_block_size,
            streaminfo.min_frame_size.unwrap_or(0),
            streaminfo.max_frame_size.unwrap_or(0),
            streaminfo.sample_rate,
            streaminfo.channels,
            streaminfo.bits_per_sample,
            streaminfo.samples.unwrap_or(0),
            print_hex(&streaminfo.md5sum)) // TODO implement LowerHex for &[u8] and submit a PR.
}

fn compare_metaflac(fname: &path::Path) {
    let metaflac = run_metaflac(fname);
    let streaminfo = read_streaminfo(fname);
    let mut mf_lines = metaflac.lines();
    let mut si_lines = streaminfo.lines();
    while let (Some(mf), Some(si)) = (mf_lines.next(), si_lines.next()) {
        if mf != si {
            println!("metaflac\n--------\n{}", metaflac);
            println!("streaminfo\n----------\n{}", streaminfo);
            panic!("metaflac disagrees on parsed streaminfo");
        }
    }
}

fn compare_decoded_stream(fname: &path::Path) {
    let ref_fname = fname.with_extension("wav");
    if !ref_fname.exists() {
        // TODO: actually, we might only want to run the test for files that
        // do exist already. It is fine to run streaminfo or decode-only tests
        // on thousands of files, but decoding thousands of files to wav before
        // running the tests will take a lot of space. For now, while the
        // number of samples is closer to 10 than to 100, this is fine.
        decode_file(fname);
    }

    // If the reference file does exist after decoding, we can compare it to
    // how Claxon decodes it, sample by sample.
    if ref_fname.exists() {
        let mut ref_wav_reader = hound::WavReader::open(ref_fname).unwrap();

        let try_file = fs::File::open(fname).unwrap();
        let try_buf_reader = io::BufReader::new(try_file);
        let mut try_flac_reader = claxon::FlacReader::new(try_buf_reader).unwrap();

        // The streaminfo test will ensure that things like bit depth and
        // sample rate match, only the actual samples are compared here.

        let mut ref_samples = ref_wav_reader.samples::<i32>();

        let samples = try_flac_reader.streaminfo().samples.unwrap();
        let n_channels = try_flac_reader.streaminfo().channels;
        let mut blocks = try_flac_reader.blocks::<i32>();
        let mut sample = 0u64;
        let mut b = 0u64;
        let mut buffer = Vec::new();

        while sample < samples {
            let block = blocks.read_next_or_eof(buffer).unwrap().unwrap();
            {
                let mut channels: Vec<_> = (0..n_channels)
                                               .map(|i| block.channel(i).iter().cloned())
                                               .collect();
                for i in 0..block.len() {
                    for ch in 0..n_channels as usize {
                        let ref_sample = ref_samples.next().map(|r| r.ok().unwrap());
                        let try_sample = channels[ch].next();
                        if ref_sample != try_sample {
                            println!("disagreement at sample {} of block {} in channel {}: \
                                      reference is {} but decoded is {}",
                                     i,
                                     b,
                                     ch,
                                     ref_sample.unwrap(),
                                     try_sample.unwrap());
                            panic!("decoding differs from reference decoder");
                        }
                    }
                }
                sample = sample + block.len() as u64;
            }
            b = b + 1;
            buffer = block.into_buffer();
        }
    }
}

// Hard-coded tests for the test samples added py populate.sh.
// This allows us to run these tests in parallel and follow progress without
// enabling --nocapture.

#[test]
fn verify_streaminfo_p0() {
    compare_metaflac(path::Path::new("testsamples/p0.flac"));
}

#[test]
fn verify_streaminfo_p1() {
    compare_metaflac(path::Path::new("testsamples/p1.flac"));
}

#[test]
fn verify_streaminfo_p2() {
    compare_metaflac(path::Path::new("testsamples/p2.flac"));
}

#[test]
fn verify_streaminfo_p3() {
    compare_metaflac(path::Path::new("testsamples/p3.flac"));
}

#[test]
fn verify_streaminfo_p4() {
    compare_metaflac(path::Path::new("testsamples/p4.flac"));
}

#[test]
fn verify_decoded_stream_p0() {
    compare_decoded_stream(path::Path::new("testsamples/p0.flac"));
}

#[test]
fn verify_decoded_stream_p1() {
    compare_decoded_stream(path::Path::new("testsamples/p1.flac"));
}

#[test]
fn verify_decoded_stream_p2() {
    compare_decoded_stream(path::Path::new("testsamples/p2.flac"));
}

#[test]
fn verify_decoded_stream_p3() {
    compare_decoded_stream(path::Path::new("testsamples/p3.flac"));
}

#[test]
fn verify_decoded_stream_p4() {
    compare_decoded_stream(path::Path::new("testsamples/p4.flac"));
}
<|endoftext|>


<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

/// Get the utility name.
#[macro_export]
macro_rules! util_name(
    () => ({
        let crate_name =  env!("CARGO_PKG_NAME");
        if crate_name.starts_with("uu_") {
            &crate_name[3..]
        } else {
            &crate_name
        }
    })
);

/// Get the executable path (as `OsString`).
#[macro_export]
macro_rules! executable_os(
    () => ({
        &std::env::args_os().next().unwrap()
    })
);

/// Get the executable path (as `String`; lossless).
#[macro_export]
macro_rules! executable(
    () => ({
        let exe = match executable_os!().to_str() {
            // * UTF-8
            Some(s) => s.to_string(),
            // * "lossless" debug format if `executable_os!()` is not well-formed UTF-8
            None => format!("{:?}", executable_os!())
        };
        &exe.to_owned()
    })
);

/// Get the executable name.
#[macro_export]
macro_rules! executable_name(
    () => ({
        &std::path::Path::new(executable_os!()).file_stem().unwrap().to_string_lossy()
    })
);

#[macro_export]
macro_rules! show(
    ($err:expr) => ({
        let e = $err;
        uucore::error::set_exit_code(e.code());
        eprintln!("{}: {}", executable_name!(), e);
    })
);

#[macro_export]
macro_rules! show_if_err(
    ($res:expr) => ({
        if let Err(e) = $res {
            show!(e);
        }
    })
);

/// Show an error to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", executable_name!());
        eprintln!($($args)+);
    })
);

/// Show a warning to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error_custom_description (
    ($err:expr,$($args:tt)+) => ({
        eprint!("{}: {}: ", executable_name!(), $err);
        eprintln!($($args)+);
    })
);

#[macro_export]
macro_rules! show_warning(
    ($($args:tt)+) => ({
        eprint!("{}: warning: ", executable_name!());
        eprintln!($($args)+);
    })
);

/// Show a bad invocation help message in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_usage_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", executable_name!());
        eprintln!($($args)+);
        eprintln!("Try `{:?} --help` for more information.", executable!());
    })
);

/// Display the provided error message, then `exit()` with the provided exit code
#[macro_export]
macro_rules! crash(
    ($exit_code:expr, $($args:tt)+) => ({
        show_error!($($args)+);
        ::std::process::exit($exit_code)
    })
);

/// Calls `exit()` with the provided exit code.
#[macro_export]
macro_rules! exit(
    ($exit_code:expr) => ({
        ::std::process::exit($exit_code)
    })
);

/// Unwraps the Result. Instead of panicking, it exists the program with the
/// provided exit code.
#[macro_export]
macro_rules! crash_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => crash!($exit_code, "{}", f),
        }
    )
);

/// Unwraps the Result. Instead of panicking, it shows the error and then
/// returns from the function with the provided exit code.
/// Assumes the current function returns an i32 value.
#[macro_export]
macro_rules! return_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => {
                show_error!("{}", f);
                return $exit_code;
            }
        }
    )
);

#[macro_export]
macro_rules! safe_write(
    ($fd:expr, $($args:tt)+) => (
        match write!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

#[macro_export]
macro_rules! safe_writeln(
    ($fd:expr, $($args:tt)+) => (
        match writeln!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

/// Unwraps the Result. Instead of panicking, it exists the program with exit
/// code 1.
#[macro_export]
macro_rules! safe_unwrap(
    ($exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => crash!(1, "{}", f.to_string())
        }
    )
);

//-- message templates

//-- message templates : general

#[macro_export]
macro_rules! snippet_list_join_oxford {
    ($conjunction:expr, $valOne:expr, $valTwo:expr) => (
        format!("{}, {} {}", $valOne, $conjunction, $valTwo)
    );
    ($conjunction:expr, $valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, snippet_list_join_inner!($conjunction, $valTwo $(, $remaining_values)*))
    );
}

#[macro_export]
macro_rules! snippet_list_join_or {
    ($valOne:expr, $valTwo:expr) => (
        format!("{} or {}", $valOne, $valTwo)
    );
    ($valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, snippet_list_join_oxford!("or", $valTwo $(, $remaining_values)*))
    );
}

//-- message templates : invalid input

#[macro_export]
macro_rules! msg_invalid_input {
    ($reason: expr) => {
        format!("invalid input: {}", $reason)
    };
}

// -- message templates : invalid input : flag

#[macro_export]
macro_rules! msg_invalid_opt_use {
    ($about:expr, $flag:expr) => {
        msg_invalid_input!(format!("The '{}' option {}", $flag, $about))
    };
    ($about:expr, $long_flag:expr, $short_flag:expr) => {
        msg_invalid_input!(format!(
            "The '{}' ('{}') option {}",
            $long_flag, $short_flag, $about
        ))
    };
}

#[macro_export]
macro_rules! msg_opt_only_usable_if {
    ($clause:expr, $flag:expr) => {
        msg_invalid_opt_use!(format!("only usable if {}", $clause), $flag)
    };
    ($clause:expr, $long_flag:expr, $short_flag:expr) => {
        msg_invalid_opt_use!(
            format!("only usable if {}", $clause),
            $long_flag,
            $short_flag
        )
    };
}

#[macro_export]
macro_rules! msg_opt_invalid_should_be {
    ($expects:expr, $received:expr, $flag:expr) => {
        msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $flag
        )
    };
    ($expects:expr, $received:expr, $long_flag:expr, $short_flag:expr) => {
        msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $long_flag,
            $short_flag
        )
    };
}

// -- message templates : invalid input : input combinations

#[macro_export]
macro_rules! msg_expects_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        msg_invalid_input!(format!("expects one of {}", snippet_list_join_or!($valOne $(, $remaining_values)*)))
    );
}

#[macro_export]
macro_rules! msg_expects_no_more_than_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        msg_invalid_input!(format!("expects no more than one of {}", snippet_list_join_or!($valOne $(, $remaining_values)*))) ;
    );
}
<commit_msg>refactor/uucore ~ reorganize macros into sections by 'type'<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

/// Get the executable path (as `OsString`).
#[macro_export]
macro_rules! executable_os(
    () => ({
        &std::env::args_os().next().unwrap()
    })
);

/// Get the executable path (as `String`; lossless).
#[macro_export]
macro_rules! executable(
    () => ({
        let exe = match executable_os!().to_str() {
            // * UTF-8
            Some(s) => s.to_string(),
            // * "lossless" debug format if `executable_os!()` is not well-formed UTF-8
            None => format!("{:?}", executable_os!())
        };
        &exe.to_owned()
    })
);

/// Get the executable name.
#[macro_export]
macro_rules! executable_name(
    () => ({
        &std::path::Path::new(executable_os!()).file_stem().unwrap().to_string_lossy()
    })
);

/// Derive the utility name.
#[macro_export]
macro_rules! util_name(
    () => ({
        let crate_name = env!("CARGO_PKG_NAME");
        if crate_name.starts_with("uu_") {
            &crate_name[3..]
        } else {
            &crate_name
        }
    })
);

//====

#[macro_export]
macro_rules! show(
    ($err:expr) => ({
        let e = $err;
        uucore::error::set_exit_code(e.code());
        eprintln!("{}: {}", executable_name!(), e);
    })
);

#[macro_export]
macro_rules! show_if_err(
    ($res:expr) => ({
        if let Err(e) = $res {
            show!(e);
        }
    })
);

/// Show an error to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", executable_name!());
        eprintln!($($args)+);
    })
);

/// Show a warning to stderr in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_error_custom_description (
    ($err:expr,$($args:tt)+) => ({
        eprint!("{}: {}: ", executable_name!(), $err);
        eprintln!($($args)+);
    })
);

#[macro_export]
macro_rules! show_warning(
    ($($args:tt)+) => ({
        eprint!("{}: warning: ", executable_name!());
        eprintln!($($args)+);
    })
);

/// Show a bad invocation help message in a similar style to GNU coreutils.
#[macro_export]
macro_rules! show_usage_error(
    ($($args:tt)+) => ({
        eprint!("{}: ", executable_name!());
        eprintln!($($args)+);
        eprintln!("Try `{:?} --help` for more information.", executable!());
    })
);

//====

/// Calls `exit()` with the provided exit code.
#[macro_export]
macro_rules! exit(
    ($exit_code:expr) => ({
        ::std::process::exit($exit_code)
    })
);

/// Display the provided error message, then `exit()` with the provided exit code
#[macro_export]
macro_rules! crash(
    ($exit_code:expr, $($args:tt)+) => ({
        show_error!($($args)+);
        ::std::process::exit($exit_code)
    })
);

/// Unwraps the Result. Instead of panicking, it exists the program with the
/// provided exit code.
#[macro_export]
macro_rules! crash_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => crash!($exit_code, "{}", f),
        }
    )
);

//====

/// Unwraps the Result. Instead of panicking, it shows the error and then
/// returns from the function with the provided exit code.
/// Assumes the current function returns an i32 value.
#[macro_export]
macro_rules! return_if_err(
    ($exit_code:expr, $exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => {
                show_error!("{}", f);
                return $exit_code;
            }
        }
    )
);

//====

#[macro_export]
macro_rules! safe_write(
    ($fd:expr, $($args:tt)+) => (
        match write!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

#[macro_export]
macro_rules! safe_writeln(
    ($fd:expr, $($args:tt)+) => (
        match writeln!($fd, $($args)+) {
            Ok(_) => {}
            Err(f) => panic!("{}", f)
        }
    )
);

/// Unwraps the Result. Instead of panicking, it exists the program with exit
/// code 1.
#[macro_export]
macro_rules! safe_unwrap(
    ($exp:expr) => (
        match $exp {
            Ok(m) => m,
            Err(f) => crash!(1, "{}", f.to_string())
        }
    )
);

//-- message templates

//-- message templates : general

#[macro_export]
macro_rules! snippet_list_join_oxford {
    ($conjunction:expr, $valOne:expr, $valTwo:expr) => (
        format!("{}, {} {}", $valOne, $conjunction, $valTwo)
    );
    ($conjunction:expr, $valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, snippet_list_join_inner!($conjunction, $valTwo $(, $remaining_values)*))
    );
}

#[macro_export]
macro_rules! snippet_list_join_or {
    ($valOne:expr, $valTwo:expr) => (
        format!("{} or {}", $valOne, $valTwo)
    );
    ($valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => (
        format!("{}, {}", $valOne, snippet_list_join_oxford!("or", $valTwo $(, $remaining_values)*))
    );
}

//-- message templates : invalid input

#[macro_export]
macro_rules! msg_invalid_input {
    ($reason: expr) => {
        format!("invalid input: {}", $reason)
    };
}

// -- message templates : invalid input : flag

#[macro_export]
macro_rules! msg_invalid_opt_use {
    ($about:expr, $flag:expr) => {
        msg_invalid_input!(format!("The '{}' option {}", $flag, $about))
    };
    ($about:expr, $long_flag:expr, $short_flag:expr) => {
        msg_invalid_input!(format!(
            "The '{}' ('{}') option {}",
            $long_flag, $short_flag, $about
        ))
    };
}

#[macro_export]
macro_rules! msg_opt_only_usable_if {
    ($clause:expr, $flag:expr) => {
        msg_invalid_opt_use!(format!("only usable if {}", $clause), $flag)
    };
    ($clause:expr, $long_flag:expr, $short_flag:expr) => {
        msg_invalid_opt_use!(
            format!("only usable if {}", $clause),
            $long_flag,
            $short_flag
        )
    };
}

#[macro_export]
macro_rules! msg_opt_invalid_should_be {
    ($expects:expr, $received:expr, $flag:expr) => {
        msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $flag
        )
    };
    ($expects:expr, $received:expr, $long_flag:expr, $short_flag:expr) => {
        msg_invalid_opt_use!(
            format!("expects {}, but was provided {}", $expects, $received),
            $long_flag,
            $short_flag
        )
    };
}

// -- message templates : invalid input : input combinations

#[macro_export]
macro_rules! msg_expects_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        msg_invalid_input!(format!("expects one of {}", snippet_list_join_or!($valOne $(, $remaining_values)*)))
    );
}

#[macro_export]
macro_rules! msg_expects_no_more_than_one_of {
    ($valOne:expr $(, $remaining_values:expr)*) => (
        msg_invalid_input!(format!("expects no more than one of {}", snippet_list_join_or!($valOne $(, $remaining_values)*))) ;
    );
}
<|endoftext|>


<commit_before>use std::io;
use std::str::FromStr;

pub struct VM {
	stack: Vec<Operator>,
}

impl VM {
	pub fn pop <'a> (&'a mut self) -> Operator {
		return self.stack.pop().expect("gg reinstall");
	}

	pub fn push <'a> (&'a mut self, op: Operator) {
		self.stack.push(op);
	}

	pub fn eval <'a> (&'a mut self, op: Operator) {
		match op {
			Operator::Add => self.add(),
			Operator::Subtract => self.subtract(),
			Operator::Multiply => self.multiply(),
			Operator::Divide => self.divide(),
			Operator::Modulus => self.modulus(),
			Operator::And => self.and(),
			Operator::Or => self.or(),
			Operator::Xor => self.xor(),
			Operator::Lshift => self.lshift(),
			Operator::Rshift => self.rshift(),
			Operator::Abs => self.abs(),
			Operator::Max => self.max(),
			Operator::Min => self.min(),
			Operator::Invert => self.invert(),
			Operator::Negate => self.negate(),
			Operator::Value(i) => self.push(Operator::Value(i)),
			Operator::Print => self.print(),
			_ => panic!("soon")
		}
	}

	// Math Functions
	pub fn add <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i+j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn subtract <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i-j,
				_ => panic!("can only subtract ints"),
			},
			_ => panic!("can only subtract ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn multiply <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i*j,
				_ => panic!("can only multiply ints"),
			},
			_ => panic!("can only multiply ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn divide <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i/j,
				_ => panic!("can only divide ints"),
			},
			_ => panic!("can only divide ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn modulus <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i % j,
				_ => panic!("can only mod ints"),
			},
			_ => panic!("can only mod ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn and <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i & j,
				_ => panic!("can only and ints"),
			},
			_ => panic!("can only and ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn or <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i | j,
				_ => panic!("can only or ints"),
			},
			_ => panic!("can only or ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn xor <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i ^ j,
				_ => panic!("can only xor ints"),
			},
			_ => panic!("can only xor ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn lshift <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i << j,
				_ => panic!("can only lshift ints"),
			},
			_ => panic!("can only lshift ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn rshift <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i >> j,
				_ => panic!("can only rshift ints"),
			},
			_ => panic!("can only rshift ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn abs <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => if i < 0{-i} else {i},
			_ => panic!("can only abs an int"),
		};
		self.push(Operator::Value(z));
	}

	pub fn max <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j > i {j} else{i},
				_ => panic!("can only max ints"),
			},
			_ => panic!("can only max ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn min <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j < i {j} else {i},
				_ => panic!("can only min ints"),
			},
			_ => panic!("can only min ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn invert <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => !i,
			_ => panic!("can only invert an int"),
		};
		self.push(Operator::Value(z));
	}

	pub fn negate <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => -i,
			_ => panic!("can only negate an int"),
		};
		self.push(Operator::Value(z));
	}

	//Stack Functions
	pub fn dup <'a> (&'a mut self) {
		let x = self.pop();
		let y = x.clone();
		self.push(x);
		self.push(y);
	}

	pub fn drop <'a> (&'a mut self) {
		self.pop();
	}

	pub fn swap <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		self.push(x);
		self.push(y);
	}

	pub fn over <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = x.clone();
		self.push(x);
		self.push(y);
		self.push(z);
	}

	pub fn rot <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = self.pop();
		self.push(x);
		self.push(z);
		self.push(y);
	}

	//Debug Functions
	pub fn print <'a> (&'a mut self) {
		let x = self.pop();
		println!("{}",match x{
			Operator::Value(i) => i,
			_ => panic!("tried to print something other than a value"),
		});
	}

}

#[derive(Clone)]
pub enum Operator {
	//stack
	Dup,
	Drop,
	Swap,
	Over,
	Rot,

	//debug
	Print,

	//math
	Add,
	Subtract,
	Multiply,
	Divide,
	Modulus,
	And,
	Or,
	Xor,
	Lshift,
	Rshift,
	Abs,
	Max,
	Min,
	Invert,
	Negate,

	//custom
	Define,

	//values and custom calls
	Value(i32),
	Other,
}

fn parse(s: &str) -> Operator {
	match s {
		//stack operations:
		"dup" => Operator::Dup,
		"drop" => Operator::Drop,
		"swap" => Operator::Swap,
		"over" => Operator::Over,
		"rot" => Operator::Rot,

		//debug operations:
		"." => Operator::Print,

		//math operations:
		"+" => Operator::Add,
		"-" => Operator::Subtract,
		"*" => Operator::Multiply,
		"/" => Operator::Divide,
		"mod" => Operator::Modulus,
		"and" => Operator::And,
		"or" => Operator::Or,
		"xor" => Operator::Xor,
		"lshift" => Operator::Lshift,
		"<<" => Operator::Lshift,
		"rshift" => Operator::Rshift,
		">>" => Operator::Rshift,
		"abs" => Operator::Abs,
		"max" => Operator::Max,
		"min" => Operator::Min,
		"invert" => Operator::Invert,
		"negate" => Operator::Negate,

		//custom definitions
		":" => Operator::Define,

		//value or custom operator
		x => {
			let y: Option<i32> = FromStr::from_str(x).ok();
			match y{
				Some(i) => Operator::Value(i),
				None => Operator::Other,
			}
		},
	}
}

fn main() {
	let mut x = io::stdin();
	let mut vm = VM {stack: vec![Operator::Print]};

	loop{
		let mut line: String = "".to_string();
		let _ = x.read_line(&mut line);

		for o in line.split(" "){
			println!("evaling: {}", o.trim());
			let b = parse(o.trim());
			vm.eval(b);
		}

		if vm.stack.len() == 0{break;}
	}
}
<commit_msg>hooking up stack ops<commit_after>use std::io;
use std::str::FromStr;

pub struct VM {
	stack: Vec<Operator>,
}

impl VM {
	pub fn pop <'a> (&'a mut self) -> Operator {
		return self.stack.pop().expect("gg reinstall");
	}

	pub fn push <'a> (&'a mut self, op: Operator) {
		self.stack.push(op);
	}

	pub fn eval <'a> (&'a mut self, op: Operator) {
		match op {
			Operator::Add => self.add(),
			Operator::Subtract => self.subtract(),
			Operator::Multiply => self.multiply(),
			Operator::Divide => self.divide(),
			Operator::Modulus => self.modulus(),
			Operator::And => self.and(),
			Operator::Or => self.or(),
			Operator::Xor => self.xor(),
			Operator::Lshift => self.lshift(),
			Operator::Rshift => self.rshift(),
			Operator::Abs => self.abs(),
			Operator::Max => self.max(),
			Operator::Min => self.min(),
			Operator::Invert => self.invert(),
			Operator::Negate => self.negate(),
			Operator::Dup => self.dup(),
			Operator::Drop => self.drop(),
			Operator::Swap => self.swap(),
			Operator::Over => self.over(),
			Operator::Rot => self.rot(),
			Operator::Value(i) => self.push(Operator::Value(i)),
			Operator::Print => self.print(),
			_ => panic!("soon")
		}
	}

	// Math Functions
	pub fn add <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i+j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn subtract <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i-j,
				_ => panic!("can only subtract ints"),
			},
			_ => panic!("can only subtract ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn multiply <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i*j,
				_ => panic!("can only multiply ints"),
			},
			_ => panic!("can only multiply ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn divide <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i/j,
				_ => panic!("can only divide ints"),
			},
			_ => panic!("can only divide ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn modulus <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i % j,
				_ => panic!("can only mod ints"),
			},
			_ => panic!("can only mod ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn and <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i & j,
				_ => panic!("can only and ints"),
			},
			_ => panic!("can only and ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn or <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i | j,
				_ => panic!("can only or ints"),
			},
			_ => panic!("can only or ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn xor <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i ^ j,
				_ => panic!("can only xor ints"),
			},
			_ => panic!("can only xor ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn lshift <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i << j,
				_ => panic!("can only lshift ints"),
			},
			_ => panic!("can only lshift ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn rshift <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i >> j,
				_ => panic!("can only rshift ints"),
			},
			_ => panic!("can only rshift ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn abs <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => if i < 0{-i} else {i},
			_ => panic!("can only abs an int"),
		};
		self.push(Operator::Value(z));
	}

	pub fn max <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j > i {j} else{i},
				_ => panic!("can only max ints"),
			},
			_ => panic!("can only max ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn min <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j < i {j} else {i},
				_ => panic!("can only min ints"),
			},
			_ => panic!("can only min ints"),
		};
		self.push(Operator::Value(z));
	}

	pub fn invert <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => !i,
			_ => panic!("can only invert an int"),
		};
		self.push(Operator::Value(z));
	}

	pub fn negate <'a> (&'a mut self) {
		let x = self.pop();
		let z = match x{
			Operator::Value(i) => -i,
			_ => panic!("can only negate an int"),
		};
		self.push(Operator::Value(z));
	}

	//Stack Functions
	pub fn dup <'a> (&'a mut self) {
		let x = self.pop();
		let y = x.clone();
		self.push(x);
		self.push(y);
	}

	pub fn drop <'a> (&'a mut self) {
		self.pop();
	}

	pub fn swap <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		self.push(x);
		self.push(y);
	}

	pub fn over <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = x.clone();
		self.push(x);
		self.push(y);
		self.push(z);
	}

	pub fn rot <'a> (&'a mut self) {
		let x = self.pop();
		let y = self.pop();
		let z = self.pop();
		self.push(x);
		self.push(z);
		self.push(y);
	}

	//Debug Functions
	pub fn print <'a> (&'a mut self) {
		let x = self.pop();
		println!("{}",match x{
			Operator::Value(i) => i,
			_ => panic!("tried to print something other than a value"),
		});
	}

}

#[derive(Clone)]
pub enum Operator {
	//stack
	Dup,
	Drop,
	Swap,
	Over,
	Rot,

	//debug
	Print,

	//math
	Add,
	Subtract,
	Multiply,
	Divide,
	Modulus,
	And,
	Or,
	Xor,
	Lshift,
	Rshift,
	Abs,
	Max,
	Min,
	Invert,
	Negate,

	//custom
	Define,

	//values and custom calls
	Value(i32),
	Other,
}

fn parse(s: &str) -> Operator {
	match s {
		//stack operations:
		"dup" => Operator::Dup,
		"drop" => Operator::Drop,
		"swap" => Operator::Swap,
		"over" => Operator::Over,
		"rot" => Operator::Rot,

		//debug operations:
		"." => Operator::Print,

		//math operations:
		"+" => Operator::Add,
		"-" => Operator::Subtract,
		"*" => Operator::Multiply,
		"/" => Operator::Divide,
		"mod" => Operator::Modulus,
		"and" => Operator::And,
		"or" => Operator::Or,
		"xor" => Operator::Xor,
		"lshift" => Operator::Lshift,
		"<<" => Operator::Lshift,
		"rshift" => Operator::Rshift,
		">>" => Operator::Rshift,
		"abs" => Operator::Abs,
		"max" => Operator::Max,
		"min" => Operator::Min,
		"invert" => Operator::Invert,
		"negate" => Operator::Negate,

		//custom definitions
		":" => Operator::Define,

		//value or custom operator
		x => {
			let y: Option<i32> = FromStr::from_str(x).ok();
			match y{
				Some(i) => Operator::Value(i),
				None => Operator::Other,
			}
		},
	}
}

fn main() {
	let mut x = io::stdin();
	let mut vm = VM {stack: vec![Operator::Print]};

	loop{
		let mut line: String = "".to_string();
		let _ = x.read_line(&mut line);

		for o in line.split(" "){
			println!("evaling: {}", o.trim());
			let b = parse(o.trim());
			vm.eval(b);
		}

		if vm.stack.len() == 0{break;}
	}
}
<|endoftext|>


<commit_before>use crate::prelude::*;

use crate::dap_session::DAPSession;
use crate::debug_protocol::*;
use std::time::Duration;
use tokio::io::AsyncBufReadExt;
use tokio::io::BufReader;
use tokio::net::{TcpListener, TcpStream};

pub struct Terminal {
    #[allow(unused)]
    connection: TcpStream,
    data: String,
}

impl Terminal {
    pub async fn create(
        terminal_kind: impl Into<String>,
        title: impl Into<String>,
        clear_sequence: Option<Vec<String>>,
        dap_session: DAPSession,
    ) -> Result<Terminal, Error> {
        let terminal_kind = terminal_kind.into();
        let title = title.into();

        let terminal_fut = async {
            if let Some(clear_sequence) = clear_sequence {
                let req_args = RunInTerminalRequestArguments {
                    args: clear_sequence,
                    cwd: String::new(),
                    env: None,
                    kind: Some(terminal_kind.clone()),
                    title: Some(title.clone()),
                };
                dap_session.send_request(RequestArguments::runInTerminal(req_args)).await?;
            }

            let listener = TcpListener::bind("127.0.0.1:0").await?;
            let addr = listener.local_addr()?;

            let accept_fut = listener.accept();

            // Run codelldb in a terminal agent mode, which sends back the tty device name (Unix)
            // or its own process id (Windows), then waits till the socket gets closed from our end.
            let executable = std::env::current_exe()?.to_str().unwrap().into();
            let args = vec![executable, "terminal-agent".into(), format!("--port={}", addr.port())];
            let req_args = RunInTerminalRequestArguments {
                args: args,
                cwd: String::new(),
                env: None,
                kind: Some(terminal_kind),
                title: Some(title),
            };
            log_errors!(dap_session.send_request(RequestArguments::runInTerminal(req_args)).await);

            let (stream, _remote_addr) = accept_fut.await?;

            let mut reader = BufReader::new(stream);
            let mut data = String::new();
            reader.read_line(&mut data).await?;

            Ok(Terminal {
                connection: reader.into_inner(),
                data: data.trim().to_owned(),
            })
        };

        match tokio::time::timeout(Duration::from_secs(5), terminal_fut).await {
            Ok(res) => res,
            Err(_) => bail!("Terminal agent did not respond within the allotted time."),
        }
    }

    pub fn input_devname(&self) -> &str {
        if cfg!(windows) {
            "CONIN$"
        } else {
            &self.data
        }
    }

    pub fn output_devname(&self) -> &str {
        if cfg!(windows) {
            "CONOUT$"
        } else {
            &self.data
        }
    }

    pub fn attach<F, R>(&self, f: F) -> R
    where
        F: FnOnce() -> R,
    {
        // Windows does not have an API for launching a child process attached to another console.
        // Instead,
        #[cfg(windows)]
        {
            use winapi::um::wincon::{AttachConsole, FreeConsole};
            let pid = self.data.parse::<u32>().unwrap();
            unsafe {
                dbg!(FreeConsole());
                dbg!(AttachConsole(pid));
            }
            let result = f();
            unsafe {
                dbg!(FreeConsole());
            }
            result
        }

        #[cfg(not(windows))]
        f()
    }
}
<commit_msg>Spawn runInTerminal request as a separate task to ensure progress.<commit_after>use crate::prelude::*;

use crate::dap_session::DAPSession;
use crate::debug_protocol::*;
use std::time::Duration;
use tokio::io::AsyncBufReadExt;
use tokio::io::BufReader;
use tokio::net::{TcpListener, TcpStream};

pub struct Terminal {
    #[allow(unused)]
    connection: TcpStream,
    data: String,
}

impl Terminal {
    pub async fn create(
        terminal_kind: impl Into<String>,
        title: impl Into<String>,
        clear_sequence: Option<Vec<String>>,
        dap_session: DAPSession,
    ) -> Result<Terminal, Error> {
        let terminal_kind = terminal_kind.into();
        let title = title.into();

        let terminal_fut = async move {
            if let Some(clear_sequence) = clear_sequence {
                let req_args = RunInTerminalRequestArguments {
                    args: clear_sequence,
                    cwd: String::new(),
                    env: None,
                    kind: Some(terminal_kind.clone()),
                    title: Some(title.clone()),
                };
                dap_session.send_request(RequestArguments::runInTerminal(req_args)).await?;
            }

            let listener = TcpListener::bind("127.0.0.1:0").await?;
            let addr = listener.local_addr()?;

            let accept_fut = listener.accept();

            // Run codelldb in a terminal agent mode, which sends back the tty device name (Unix)
            // or its own process id (Windows), then waits till the socket gets closed from our end.
            let executable = std::env::current_exe()?.to_str().unwrap().into();
            let args = vec![executable, "terminal-agent".into(), format!("--port={}", addr.port())];
            let req_args = RunInTerminalRequestArguments {
                args: args,
                cwd: String::new(),
                env: None,
                kind: Some(terminal_kind),
                title: Some(title),
            };

            tokio::spawn(async move {
                let response = dap_session.send_request(RequestArguments::runInTerminal(req_args));
                log_errors!(response.await);
            });

            let (stream, _remote_addr) = accept_fut.await?;
            let mut reader = BufReader::new(stream);
            let mut data = String::new();
            reader.read_line(&mut data).await?;

            Ok(Terminal {
                connection: reader.into_inner(),
                data: data.trim().to_owned(),
            })
        };

        match tokio::time::timeout(Duration::from_secs(300), terminal_fut).await {
            Ok(res) => res,
            Err(_) => bail!("Terminal agent did not respond within the allotted time."),
        }
    }

    pub fn input_devname(&self) -> &str {
        if cfg!(windows) {
            "CONIN$"
        } else {
            &self.data
        }
    }

    pub fn output_devname(&self) -> &str {
        if cfg!(windows) {
            "CONOUT$"
        } else {
            &self.data
        }
    }

    pub fn attach<F, R>(&self, f: F) -> R
    where
        F: FnOnce() -> R,
    {
        // Windows does not have an API for launching a child process attached to another console.
        // Instead,
        #[cfg(windows)]
        {
            use winapi::um::wincon::{AttachConsole, FreeConsole};
            let pid = self.data.parse::<u32>().unwrap();
            unsafe {
                dbg!(FreeConsole());
                dbg!(AttachConsole(pid));
            }
            let result = f();
            unsafe {
                dbg!(FreeConsole());
            }
            result
        }

        #[cfg(not(windows))]
        f()
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#[macro_use]
extern crate enum_primitive;
#[macro_use]
extern crate conrod;
extern crate rustc_serialize;
extern crate time;
extern crate piston_window;

mod arena;
mod db;
mod graphic;
mod player;

use player::Player;
use player::PlayerType;
use arena::Arena;
use db::enums;

fn main() {
    println!("");
    println!("Hello and Welcome to the Pokemon Battle Arena");
    println!("");
    testing();
}

// This function is for testing. Pls uncommend before commiting!
fn testing() {

    println!("Testing:");
    for entry in db::movedex::Movedex::new().get_entries() {
        if entry.get_category() == enums::MoveCategory::WholeFieldEffect {
            println!("{:?}", entry.get_name());
        }
    }
    // test_players();
    // test_arena();
    // graphic::gui::draw_window();
}

fn test_players() {

    println!("The Player Section");
    let mut human = Player::new_by_id(&[5, 3, 17], PlayerType::Human);

    println!("Creating a player and testing count and getting the name");
    println!("Count: {}", human.get_pokemon_count());
    println!("Place 1: {}", human.get_pokemon_list()[0].get_name());
    println!("Place 2: {}", human.get_pokemon_list()[1].get_name());
    println!("Place 3: {}", human.get_pokemon_list()[2].get_name());

    println!("Alive list:");
    println!("Number: {}", human.get_alive_count());
    println!("List: {:#?}", human.get_alive_list());

    println!("Current:");
    println!("Default: {}", human.get_current());
    human.set_current(2);
    println!("Custom: {}", human.get_current());
}

fn test_arena() {
    // Arena erstellen
    let mut p1 = Player::new_by_id(&[5], PlayerType::Human);
    let mut p2 = Player::new_by_id(&[8], PlayerType::Human);
    let mut arena = Arena::new(&mut p1,
                               &mut p2,
                               db::enums::Types::Normal,
                               db::enums::Weather::ClearSky);
    // println!("Player One: {:#?}", arena.get_player_one());
    // println!("Player Two: {:#?}", arena.get_player_two());
    // Attacke erstellen und "Kampf"
    let movedex = db::movedex::Movedex::new();
    let attack = movedex.move_by_id(1).unwrap();
    let attack_haze = movedex.move_by_id(114).unwrap();
    let attack_hail = movedex.move_by_id(258).unwrap();
    let attack_sandstorm = movedex.move_by_id(201).unwrap();
    let attack_mudsport = movedex.move_by_id(300).unwrap();
    let attack_fairylock = movedex.move_by_id(587).unwrap();
    println!("Attack: {}", attack_hail.get_name());
    println!("HP1 vorher: {}",
             arena.get_player_one().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    println!("HP2 vorher: {}",
             arena.get_player_two().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    attack.resolve(&mut arena, 2);
    attack_hail.resolve(&mut arena, 2);
    attack_haze.resolve(&mut arena, 2);
    attack_sandstorm.resolve(&mut arena, 2);
    attack_mudsport.resolve(&mut arena, 2);
    attack_fairylock.resolve(&mut arena, 2);
    attack.resolve(&mut arena, 2);

    println!("HP1 nachher: {}",
             arena.get_player_one().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    println!("HP2 nachher: {}",
             arena.get_player_two().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    println!("Hash vorher: {:?}", arena.get_field_effects());
    println!("Weather vorher: {:?}", arena.get_current_weather());
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    println!("Hash nach 2 Runden: {:?}", arena.get_field_effects());
    println!("Weather nach 2 Runden: {:?}", arena.get_current_weather());
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    println!("Hash nach 5 Runden: {:?}", arena.get_field_effects());
    println!("Weather nach 5 Runden: {:?}", arena.get_current_weather());
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    println!("Hash nach 7 Runden: {:?}", arena.get_field_effects());
    println!("Weather nach 7 Runden: {:?}", arena.get_current_weather());
    // println!("Player One: {:#?}", arena.get_player_one());
}
<commit_msg>main commit<commit_after>#![allow(dead_code)]
#[macro_use]
extern crate enum_primitive;
#[macro_use]
extern crate conrod;
extern crate rustc_serialize;
extern crate time;
extern crate piston_window;

mod arena;
mod db;
mod graphic;
mod player;

use player::Player;
use player::PlayerType;
use arena::Arena;
use db::enums;

fn main() {
    println!("");
    println!("Hello and Welcome to the Pokemon Battle Arena");
    println!("");
    testing();
}

// This function is for testing. Pls uncommend before commiting!
fn testing() {

    println!("Testing:");
    for entry in db::movedex::Movedex::new().get_entries() {
        if entry.get_category() == enums::MoveCategory::WholeFieldEffect {
            println!("{:?}", entry.get_name());
        }
    }
    // test_players();
    // test_arena();
    // graphic::gui::draw_window();
}

fn test_players() {

    println!("The Player Section");
    let mut human = Player::new_by_id(&[5, 3, 17], PlayerType::Human);

    println!("Creating a player and testing count and getting the name");
    println!("Count: {}", human.get_pokemon_count());
    println!("Place 1: {}", human.get_pokemon_list()[0].get_name());
    println!("Place 2: {}", human.get_pokemon_list()[1].get_name());
    println!("Place 3: {}", human.get_pokemon_list()[2].get_name());

    println!("Alive list:");
    println!("Number: {}", human.get_alive_count());
    println!("List: {:#?}", human.get_alive_list());

    println!("Current:");
    println!("Default: {}", human.get_current());
    human.set_current(2);
    println!("Custom: {}", human.get_current());
}

fn test_arena() {
    // Arena erstellen
    let mut p1 = Player::new_by_id(&[5], PlayerType::Human);
    let mut p2 = Player::new_by_id(&[8], PlayerType::Human);
    let mut arena = Arena::new(&mut p1,
                               &mut p2,
                               db::enums::Types::Normal,
                               db::enums::Weather::ClearSky);
    // println!("Player One: {:#?}", arena.get_player_one());
    // println!("Player Two: {:#?}", arena.get_player_two());
    // Attacke erstellen und "Kampf"
    let movedex = db::movedex::Movedex::new();
    let attack = movedex.move_by_id(1).unwrap();
    let attack_haze = movedex.move_by_id(114).unwrap();
    let attack_hail = movedex.move_by_id(258).unwrap();
    let attack_sandstorm = movedex.move_by_id(201).unwrap();
    let attack_mudsport = movedex.move_by_id(300).unwrap();
    let attack_fairylock = movedex.move_by_id(587).unwrap();
    println!("Attack: {}", attack_hail.get_name());
    println!("HP1 vorher: {}",
             arena.get_player_one().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    println!("HP2 vorher: {}",
             arena.get_player_two().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    attack.resolve(&mut arena, enums::Player::Two);
    attack_hail.resolve(&mut arena, enums::Player::Two);
    attack_haze.resolve(&mut arena, enums::Player::Two);
    attack_sandstorm.resolve(&mut arena, enums::Player::Two);
    attack_mudsport.resolve(&mut arena, enums::Player::Two);
    attack_fairylock.resolve(&mut arena, enums::Player::Two);
    attack.resolve(&mut arena, enums::Player::Two);

    println!("HP1 nachher: {}",
             arena.get_player_one().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    println!("HP2 nachher: {}",
             arena.get_player_two().get_pokemon_list()[0]
                 .get_current()
                 .get_stat(&db::enums::Stats::Hp));
    println!("Hash vorher: {:?}", arena.get_field_effects());
    println!("Weather vorher: {:?}", arena.get_current_weather());
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    println!("Hash nach 2 Runden: {:?}", arena.get_field_effects());
    println!("Weather nach 2 Runden: {:?}", arena.get_current_weather());
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    println!("Hash nach 5 Runden: {:?}", arena.get_field_effects());
    println!("Weather nach 5 Runden: {:?}", arena.get_current_weather());
    arena.validate_effects_and_weather();
    arena.validate_effects_and_weather();
    println!("Hash nach 7 Runden: {:?}", arena.get_field_effects());
    println!("Weather nach 7 Runden: {:?}", arena.get_current_weather());
    // println!("Player One: {:#?}", arena.get_player_one());
}
<|endoftext|>


<commit_before>#![feature(plugin, custom_attribute)]
#![plugin(holyjit_plugin)]
#![feature(unboxed_closures)]
#[macro_use] extern crate holyjit_lib as hj;

jit!{ fn eval(jc: hj::JitContext, program: String) -> Result<(), ()> = eval_impl in jc; }
fn eval_impl(_jc: hj::JitContext, program: String) -> Result<(), ()> {
    let prog = program.as_bytes();
    let mut pc : usize = 0;
    let mut val : u8 = 0;
    let mut mem : Vec<u8> = Vec::with_capacity(256);
    mem.resize(256, 0);
    loop {
        if pc >= prog.len() {
            return Ok(());
        }
        match prog[pc] {
            b'>' => { val += 1; }
            b'<' => { val -= 1; }
            b'-' => { mem[val as usize] -= 1; }
            b'+' => { mem[val as usize] += 1; }
            b'.' => { panic!("putchar: NYI"); }
            b',' => { panic!("getchar: NYI"); }
            b'[' => {
                if val == 0 {
                    let mut iter = (pc + 1, 0);
                    loop {
                        iter = match (iter, prog[iter.0]) {
                            ((p, 0), b']') => {
                                pc = p + 1;
                                break;
                            },
                            ((p, d), b'[') => (p + 1, d + 1),
                            ((p, d), b']') => (p + 1, d - 1),
                            ((p, d), _) => (p + 1, d)
                        }
                    }
                }
            }
            b']' => {
                let mut iter = (pc - 1, 0);
                loop {
                    iter = match (iter, prog[iter.0]) {
                        ((p, 0), b'[') => {
                            pc = p;
                            break;
                        },
                        ((p, d), b'[') => (p - 1, d + 1),
                        ((p, d), b']') => (p - 1, d - 1),
                        ((p, d), _) => (p - 1, d)
                    }
                }
            }
            _ => { panic!("Unknown Symbol"); }
        }
        pc += 1;
    }
}

fn main() {
    let jc : hj::JitContext = Default::default();
    let res = eval(jc, "++".into());
    res.unwrap();
}
<commit_msg>Fix loops and memory model of the Brainfuck interpreter.<commit_after>#![feature(plugin, custom_attribute)]
#![plugin(holyjit_plugin)]
#![feature(unboxed_closures)]
#[macro_use] extern crate holyjit_lib as hj;

jit!{ fn eval(jc: hj::JitContext, program: String) -> Result<(), ()> = eval_impl in jc; }
fn eval_impl(_jc: hj::JitContext, program: String) -> Result<(), ()> {
    let prog = program.as_bytes();
    let mut pc : usize = 0;
    let mut ptr : usize = 0;
    let mut mem : Vec<u8> = Vec::with_capacity(256);
    mem.resize(256, 0);
    loop {
        if pc >= prog.len() {
            return Ok(());
        }
        match prog[pc] {
            b'>' => {
                ptr += 1;
                if ptr >= mem.len() {
                    mem.push(0);
                }
            }
            b'<' => { ptr = ptr.saturating_sub(1); }
            b'-' => { mem[ptr] = mem[ptr].wrapping_sub(1); }
            b'+' => { mem[ptr] = mem[ptr].wrapping_add(1); }
            b'.' => { panic!("putchar: NYI"); }
            b',' => { panic!("getchar: NYI"); }
            b'[' => {
                if mem[ptr] == 0 {
                    let mut iter = (pc + 1, 0);
                    loop {
                        iter = match (iter, prog[iter.0]) {
                            ((p, 0), b']') => {
                                pc = p + 1;
                                break;
                            },
                            ((p, d), b'[') => (p + 1, d + 1),
                            ((p, d), b']') => (p + 1, d - 1),
                            ((p, d), _) => (p + 1, d)
                        }
                    }
                    continue; // skip pc increment
                }
            }
            b']' => {
                let mut iter = (pc - 1, 0);
                loop {
                    iter = match (iter, prog[iter.0]) {
                        ((p, 0), b'[') => {
                            pc = p;
                            break;
                        },
                        ((p, d), b'[') => (p - 1, d + 1),
                        ((p, d), b']') => (p - 1, d - 1),
                        ((p, d), _) => (p - 1, d)
                    }
                }
                continue; // skip pc increment
            }
            _ => { panic!("Unknown Symbol"); }
        }
        pc += 1;
    }
}

fn main() {
    let jc : hj::JitContext = Default::default();
    let res = eval(jc, "++".into());
    res.unwrap();
}
<|endoftext|>