<commit_before>use std::default:: { Default };
use std::collections:: { HashMap };
use std::ops::AddAssign;
use branch:: { BranchUnit };
use lcov_parser:: { LineData, FunctionData, BranchData };

type LineNumber = u32;
type ExecutionCount = u32;
type FunctionName = String;

pub type TestSum = Test;

#[derive(Debug,Clone)]
pub struct Test {
    line: HashMap<LineNumber, ExecutionCount>,
    func: HashMap<FunctionName, ExecutionCount>,
    branch: HashMap<LineNumber, HashMap<BranchUnit, ExecutionCount>>
}

impl Default for Test {
    fn default() -> Self {
        Test {
            line: HashMap::new(),
            func: HashMap::new(),
            branch: HashMap::new()
        }
    }
}

impl Test {
    pub fn new() -> Self {
        Test {
            line: HashMap::new(),
            branch: HashMap::new(),
            func: HashMap::new()
        }
    }
    pub fn lines(&self) -> &HashMap<LineNumber, ExecutionCount> {
        &self.line
    }
    pub fn functions(&self) -> &HashMap<FunctionName, ExecutionCount> {
        &self.func
    }
    pub fn branches(&self) -> &HashMap<LineNumber, HashMap<BranchUnit, ExecutionCount>> {
        &self.branch
    }

    /// Add the number of times of execution of the line
    ///
    /// # Examples
    ///
    /// ```
    /// use lcov_merge::TestSum;
    ///
    /// let mut sum = TestSum::default();
    /// sum.add_line_count(&1, &1);
    /// sum.add_line_count(&1, &2);
    ///
    /// assert_eq!(sum.get_line_count(&1), Some(&3));
    /// ```
    pub fn add_line_count(&mut self, line_number: &u32, exec_count: &u32) {
        let mut line_count = self.line.entry(line_number.clone())
            .or_insert(0);
        *line_count += *exec_count;
    }

    pub fn get_line_count(&self, line_number: &u32) -> Option<&u32> {
        self.line.get(line_number)
    }

    pub fn add_func_count(&mut self, func_name: &String, exec_count: &u32) {
        let mut func_count = self.func.entry(func_name.clone())
            .or_insert(0);
        *func_count += *exec_count;
    }

    pub fn get_func_count(&self, func_name: &String) -> Option<&u32> {
        self.func.get(func_name)
    }

    /// Add the number of times of execution of the branch
    ///
    /// # Examples
    ///
    /// ```
    /// use lcov_merge:: { TestSum, BranchUnit };
    ///
    /// let mut sum = TestSum::default();
    /// sum.add_branch_count(&1, &BranchUnit::new(1, 1), &1);
    /// sum.add_branch_count(&1, &BranchUnit::new(1, 1), &2);
    ///
    /// let branch = sum.get_branch_count(&1);
    /// let branch_count = branch.unwrap().get(&BranchUnit::new(1, 1));
    ///
    /// assert_eq!(branch_count, Some(&3));
    /// ```
    pub fn add_branch_count(&mut self, line_number: &u32, unit: &BranchUnit, exec_count: &u32) {
        let mut branch = self.branch.entry(line_number.clone())
            .or_insert(HashMap::new());

        let mut branch_count = branch.entry(unit.clone())
            .or_insert(0);

        *branch_count += *exec_count;
    }

    pub fn get_branch_count(&self, line_number: &u32) -> Option<&HashMap<BranchUnit, u32>> {
        self.branch.get(line_number)
    }
}

impl<'a> AddAssign<&'a LineData> for Test {
    fn add_assign(&mut self, data: &'a LineData) {
        let mut line_count = self.line.entry(data.line)
            .or_insert(0);
        *line_count += data.count;
    }
}

impl<'a> AddAssign<&'a FunctionData> for Test {
    fn add_assign(&mut self, data: &'a FunctionData) {
        let mut func_count = self.func.entry(data.name.clone())
            .or_insert(0);
        *func_count += data.count;
    }
}

impl<'a> AddAssign<&'a BranchData> for Test {
    fn add_assign(&mut self, data: &'a BranchData) {
        let unit = BranchUnit::new(data.block, data.branch);

        let mut branch = self.branch.entry(data.line)
            .or_insert(HashMap::new());

        let mut branch_count = branch.entry(unit)
            .or_insert(0);

        *branch_count += data.taken;
    }
}

impl<'a> AddAssign<&'a Test> for Test {
    fn add_assign(&mut self, other: &'a Test) {
        let lines = other.lines();

        for (line, count) in lines.iter() {
            if self.line.contains_key(line) {
                let current_count = self.line.get_mut(line).unwrap();
                *current_count += *count;
            } else {
                self.line.insert(*line, *count);
            }
        }

        let functions = other.functions();

        for (name, count) in functions.iter() {
            if self.func.contains_key(name) {
                let current_count = self.func.get_mut(name).unwrap();
                *current_count += *count;
            } else {
                self.func.insert(name.clone(), *count);
            }
        }

        let branches = other.branches();

        for (line, branch) in branches.iter() {
            if self.branch.contains_key(line) {
                let current_branch_count = self.branch.get_mut(line).unwrap();

                for (unit, count) in branch.iter() {
                    if current_branch_count.contains_key(unit) {
                        let current_count = current_branch_count.get_mut(unit).unwrap();
                        *current_count += *count;
                    } else {
                        current_branch_count.insert(unit.clone(), *count);
                    }
                }
            } else {
                self.branch.insert(*line, branch.clone());
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections:: { HashMap };
    use test:: { Test };
    use branch:: { BranchUnit };
    use lcov_parser:: { LineData, FunctionData, BranchData };

    #[test]
    fn add_line_data() {
        let mut test = Test::new();

        test += &LineData { line: 1, count: 1, checksum: None };
        assert_eq!( test.get_line_count(&1), Some(&1u32) );

        test += &LineData { line: 1, count: 1, checksum: None };
        assert_eq!( test.get_line_count(&1), Some(&2u32) );
    }

    #[test]
    fn add_func_data() {
        let mut test = Test::new();

        test += &FunctionData { name: "main".to_string(), count: 1 };
        assert_eq!( test.get_func_count(&"main".to_string()), Some(&1u32) );

        test += &FunctionData { name: "main".to_string(), count: 1 };
        assert_eq!( test.get_func_count(&"main".to_string()), Some(&2u32) );
    }

    #[test]
    fn add_branch_data() {
        let mut test = Test::new();

        test += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };

        let mut first_branch_count = HashMap::new();
        first_branch_count.insert(BranchUnit::new(1, 1), 1);

        assert_eq!( test.get_branch_count(&1), Some(&first_branch_count) );

        test += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };

        let mut second_branch_count = HashMap::new();
        second_branch_count.insert(BranchUnit::new(1, 1), 2);

        assert_eq!( test.get_branch_count(&1), Some(&second_branch_count) );
    }

    #[test]
    fn add_test_data() {
        let mut test1 = Test::new();
        test1 += &LineData { line: 1, count: 1, checksum: None };
        test1 += &FunctionData { name: "main".to_string(), count: 1 };
        test1 += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };

        let test2 = {
            let mut test2 = Test::new();
            test2 += &LineData { line: 1, count: 1, checksum: None };
            test2 += &FunctionData { name: "main".to_string(), count: 1 };
            test2 += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };
            test2
        };
        test1 += &test2;

        assert_eq!( test1.get_line_count(&1), Some(&2u32) );
        assert_eq!( test1.get_func_count(&"main".to_string()), Some(&2u32) );

        let mut second_branch_count = HashMap::new();
        second_branch_count.insert(BranchUnit::new(1, 1), 2);

        assert_eq!( test1.get_branch_count(&1), Some(&second_branch_count) );
    }
}
<commit_msg>fix add test<commit_after>use std::default:: { Default };
use std::collections:: { HashMap };
use std::ops::AddAssign;
use branch:: { BranchUnit };
use line:: { Lines };
use lcov_parser:: { LineData, FunctionData, BranchData };

type LineNumber = u32;
type ExecutionCount = u32;
type FunctionName = String;

pub type TestSum = Test;

#[derive(Debug,Clone)]
pub struct Test {
    line: Lines,
    func: HashMap<FunctionName, ExecutionCount>,
    branch: HashMap<LineNumber, HashMap<BranchUnit, ExecutionCount>>
}

impl Default for Test {
    fn default() -> Self {
        Test {
            line: Lines::new(),
            func: HashMap::new(),
            branch: HashMap::new()
        }
    }
}

impl Test {
    pub fn new() -> Self {
        Test {
            line: Lines::new(),
            branch: HashMap::new(),
            func: HashMap::new()
        }
    }
    pub fn lines(&self) -> &Lines {
        &self.line
    }
    pub fn functions(&self) -> &HashMap<FunctionName, ExecutionCount> {
        &self.func
    }
    pub fn branches(&self) -> &HashMap<LineNumber, HashMap<BranchUnit, ExecutionCount>> {
        &self.branch
    }

    pub fn get_line_count(&self, line_number: &u32) -> Option<&u32> {
        self.line.get(line_number)
    }

    pub fn add_func_count(&mut self, func_name: &String, exec_count: &u32) {
        let mut func_count = self.func.entry(func_name.clone())
            .or_insert(0);
        *func_count += *exec_count;
    }

    pub fn get_func_count(&self, func_name: &String) -> Option<&u32> {
        self.func.get(func_name)
    }

    /// Add the number of times of execution of the branch
    ///
    /// # Examples
    ///
    /// ```
    /// use lcov_merge:: { TestSum, BranchUnit };
    ///
    /// let mut sum = TestSum::default();
    /// sum.add_branch_count(&1, &BranchUnit::new(1, 1), &1);
    /// sum.add_branch_count(&1, &BranchUnit::new(1, 1), &2);
    ///
    /// let branch = sum.get_branch_count(&1);
    /// let branch_count = branch.unwrap().get(&BranchUnit::new(1, 1));
    ///
    /// assert_eq!(branch_count, Some(&3));
    /// ```
    pub fn add_branch_count(&mut self, line_number: &u32, unit: &BranchUnit, exec_count: &u32) {
        let mut branch = self.branch.entry(line_number.clone())
            .or_insert(HashMap::new());

        let mut branch_count = branch.entry(unit.clone())
            .or_insert(0);

        *branch_count += *exec_count;
    }

    pub fn get_branch_count(&self, line_number: &u32) -> Option<&HashMap<BranchUnit, u32>> {
        self.branch.get(line_number)
    }
}

impl<'a> AddAssign<&'a LineData> for Test {
    fn add_assign(&mut self, data: &'a LineData) {
        self.line += data;

//        let mut line_count = self.line.entry(data.line)
//            .or_insert(0);
//        *line_count += data.count;
    }
}

impl<'a> AddAssign<&'a FunctionData> for Test {
    fn add_assign(&mut self, data: &'a FunctionData) {
        let mut func_count = self.func.entry(data.name.clone())
            .or_insert(0);
        *func_count += data.count;
    }
}

impl<'a> AddAssign<&'a BranchData> for Test {
    fn add_assign(&mut self, data: &'a BranchData) {
        let unit = BranchUnit::new(data.block, data.branch);

        let mut branch = self.branch.entry(data.line)
            .or_insert(HashMap::new());

        let mut branch_count = branch.entry(unit)
            .or_insert(0);

        *branch_count += data.taken;
    }
}

impl<'a> AddAssign<&'a Test> for Test {
    fn add_assign(&mut self, other: &'a Test) {
        self.line += other.lines();

        let functions = other.functions();

        for (name, count) in functions.iter() {
            if self.func.contains_key(name) {
                let current_count = self.func.get_mut(name).unwrap();
                *current_count += *count;
            } else {
                self.func.insert(name.clone(), *count);
            }
        }

        let branches = other.branches();

        for (line, branch) in branches.iter() {
            if self.branch.contains_key(line) {
                let current_branch_count = self.branch.get_mut(line).unwrap();

                for (unit, count) in branch.iter() {
                    if current_branch_count.contains_key(unit) {
                        let current_count = current_branch_count.get_mut(unit).unwrap();
                        *current_count += *count;
                    } else {
                        current_branch_count.insert(unit.clone(), *count);
                    }
                }
            } else {
                self.branch.insert(*line, branch.clone());
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections:: { HashMap };
    use test:: { Test };
    use branch:: { BranchUnit };
    use lcov_parser:: { LineData, FunctionData, BranchData };

    #[test]
    fn add_line_data() {
        let mut test = Test::new();

        test += &LineData { line: 1, count: 1, checksum: None };
        assert_eq!( test.get_line_count(&1), Some(&1u32) );

        test += &LineData { line: 1, count: 1, checksum: None };
        assert_eq!( test.get_line_count(&1), Some(&2u32) );
    }

    #[test]
    fn add_func_data() {
        let mut test = Test::new();

        test += &FunctionData { name: "main".to_string(), count: 1 };
        assert_eq!( test.get_func_count(&"main".to_string()), Some(&1u32) );

        test += &FunctionData { name: "main".to_string(), count: 1 };
        assert_eq!( test.get_func_count(&"main".to_string()), Some(&2u32) );
    }

    #[test]
    fn add_branch_data() {
        let mut test = Test::new();

        test += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };

        let mut first_branch_count = HashMap::new();
        first_branch_count.insert(BranchUnit::new(1, 1), 1);

        assert_eq!( test.get_branch_count(&1), Some(&first_branch_count) );

        test += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };

        let mut second_branch_count = HashMap::new();
        second_branch_count.insert(BranchUnit::new(1, 1), 2);

        assert_eq!( test.get_branch_count(&1), Some(&second_branch_count) );
    }

    #[test]
    fn add_test_data() {
        let mut test1 = Test::new();
        test1 += &LineData { line: 1, count: 1, checksum: None };
        test1 += &FunctionData { name: "main".to_string(), count: 1 };
        test1 += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };

        let test2 = {
            let mut test2 = Test::new();
            test2 += &LineData { line: 1, count: 1, checksum: None };
            test2 += &FunctionData { name: "main".to_string(), count: 1 };
            test2 += &BranchData { line: 1, block: 1, branch: 1, taken: 1 };
            test2
        };
        test1 += &test2;

        assert_eq!( test1.get_line_count(&1), Some(&2u32) );
        assert_eq!( test1.get_func_count(&"main".to_string()), Some(&2u32) );

        let mut second_branch_count = HashMap::new();
        second_branch_count.insert(BranchUnit::new(1, 1), 2);

        assert_eq!( test1.get_branch_count(&1), Some(&second_branch_count) );
    }
}
<|endoftext|>


<commit_before>//! Various helpers for Actix applications to use during testing.
use std::cell::RefCell;
use std::rc::Rc;

use actix_http::cookie::Cookie;
use actix_http::http::header::{Header, HeaderName, IntoHeaderValue};
use actix_http::http::{HttpTryFrom, Method, StatusCode, Version};
use actix_http::test::TestRequest as HttpTestRequest;
use actix_http::{Extensions, PayloadStream, Request};
use actix_router::{Path, ResourceDef, Url};
use actix_rt::Runtime;
use actix_server_config::ServerConfig;
use actix_service::{FnService, IntoNewService, NewService, Service};
use bytes::Bytes;
use futures::future::{lazy, Future};

use crate::config::{AppConfig, AppConfigInner};
use crate::data::RouteData;
use crate::dev::{Body, Payload};
use crate::request::HttpRequestPool;
use crate::rmap::ResourceMap;
use crate::service::{ServiceRequest, ServiceResponse};
use crate::{Error, HttpRequest, HttpResponse};

thread_local! {
    static RT: RefCell<Runtime> = {
        RefCell::new(Runtime::new().unwrap())
    };
}

/// Runs the provided future, blocking the current thread until the future
/// completes.
///
/// This function can be used to synchronously block the current thread
/// until the provided `future` has resolved either successfully or with an
/// error. The result of the future is then returned from this function
/// call.
///
/// Note that this function is intended to be used only for testing purpose.
/// This function panics on nested call.
pub fn block_on<F>(f: F) -> Result<F::Item, F::Error>
where
    F: Future,
{
    RT.with(move |rt| rt.borrow_mut().block_on(f))
}

/// Runs the provided function, with runtime enabled.
///
/// Note that this function is intended to be used only for testing purpose.
/// This function panics on nested call.
pub fn run_on<F, R>(f: F) -> R
where
    F: Fn() -> R,
{
    RT.with(move |rt| rt.borrow_mut().block_on(lazy(|| Ok::<_, ()>(f()))))
        .unwrap()
}

/// Create service that always responds with `HttpResponse::Ok()`
pub fn ok_service() -> impl Service<
    Request = ServiceRequest<PayloadStream>,
    Response = ServiceResponse<Body>,
    Error = Error,
> {
    default_service(StatusCode::OK)
}

/// Create service that responds with response with specified status code
pub fn default_service(
    status_code: StatusCode,
) -> impl Service<
    Request = ServiceRequest<PayloadStream>,
    Response = ServiceResponse<Body>,
    Error = Error,
> {
    FnService::new(move |req: ServiceRequest<PayloadStream>| {
        req.into_response(HttpResponse::build(status_code).finish())
    })
}

/// This method accepts application builder instance, and constructs
/// service.
///
/// ```rust,ignore
/// use actix_service::Service;
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
///
/// fn main() {
///     let mut app = test::init_service(
///         App::new()
///             .service(web::resource("/test").to(|| HttpResponse::Ok()))
///     );
///
///     // Create request object
///     let req = test::TestRequest::with_uri("/test").to_request();
///
///     // Execute application
///     let resp = test::block_on(app.call(req)).unwrap();
///     assert_eq!(resp.status(), StatusCode::OK);
/// }
/// ```
pub fn init_service<R, S, B, E>(
    app: R,
) -> impl Service<Request = Request, Response = ServiceResponse<B>, Error = E>
where
    R: IntoNewService<S, ServerConfig>,
    S: NewService<
        ServerConfig,
        Request = Request,
        Response = ServiceResponse<B>,
        Error = E,
    >,
    S::InitError: std::fmt::Debug,
{
    let cfg = ServerConfig::new("127.0.0.1:8080".parse().unwrap());
    block_on(app.into_new_service().new_service(&cfg)).unwrap()
}

/// Calls service and waits for response future completion.
///
/// ```rust,ignore
/// use actix_web::{test, App, HttpResponse, http::StatusCode};
/// use actix_service::Service;
///
/// fn main() {
///     let mut app = test::init_service(
///         App::new()
///             .service(web::resource("/test").to(|| HttpResponse::Ok()))
///     );
///
///     // Create request object
///     let req = test::TestRequest::with_uri("/test").to_request();
///
///     // Call application
///     let resp = test::call_succ_service(&mut app, req);
///     assert_eq!(resp.status(), StatusCode::OK);
/// }
/// ```
pub fn call_success<S, R, B, E>(app: &mut S, req: R) -> S::Response
where
    S: Service<Request = R, Response = ServiceResponse<B>, Error = E>,
    E: std::fmt::Debug,
{
    block_on(app.call(req)).unwrap()
}

/// Test `Request` builder.
///
/// For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern.
/// You can generate various types of request via TestRequest's methods:
///  * `TestRequest::to_request` creates `actix_http::Request` instance.
///  * `TestRequest::to_service` creates `ServiceRequest` instance, which is used for testing middlewares and chain adapters.
///  * `TestRequest::to_from` creates `ServiceFromRequest` instance, which is used for testing extractors.
///  * `TestRequest::to_http_request` creates `HttpRequest` instance, which is used for testing handlers.
///
/// ```rust,ignore
/// # use futures::IntoFuture;
/// use actix_web::{test, HttpRequest, HttpResponse, HttpMessage};
/// use actix_web::http::{header, StatusCode};
///
/// fn index(req: HttpRequest) -> HttpResponse {
///     if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
///         HttpResponse::Ok().into()
///     } else {
///         HttpResponse::BadRequest().into()
///     }
/// }
///
/// fn main() {
///     let req = test::TestRequest::with_header("content-type", "text/plain")
///         .to_http_request();
///
///     let resp = test::block_on(index(req).into_future()).unwrap();
///     assert_eq!(resp.status(), StatusCode::OK);
///
///     let req = test::TestRequest::default().to_http_request();
///     let resp = test::block_on(index(req).into_future()).unwrap();
///     assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
/// }
/// ```
pub struct TestRequest {
    req: HttpTestRequest,
    rmap: ResourceMap,
    config: AppConfigInner,
    route_data: Extensions,
}

impl Default for TestRequest {
    fn default() -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            config: AppConfigInner::default(),
            route_data: Extensions::new(),
        }
    }
}

#[allow(clippy::wrong_self_convention)]
impl TestRequest {
    /// Create TestRequest and set request uri
    pub fn with_uri(path: &str) -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().uri(path).take(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            config: AppConfigInner::default(),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set header
    pub fn with_hdr<H: Header>(hdr: H) -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().set(hdr).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set header
    pub fn with_header<K, V>(key: K, value: V) -> TestRequest
    where
        HeaderName: HttpTryFrom<K>,
        V: IntoHeaderValue,
    {
        TestRequest {
            req: HttpTestRequest::default().header(key, value).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set method to `Method::GET`
    pub fn get() -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().method(Method::GET).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set method to `Method::POST`
    pub fn post() -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().method(Method::POST).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Set HTTP version of this request
    pub fn version(mut self, ver: Version) -> Self {
        self.req.version(ver);
        self
    }

    /// Set HTTP method of this request
    pub fn method(mut self, meth: Method) -> Self {
        self.req.method(meth);
        self
    }

    /// Set HTTP Uri of this request
    pub fn uri(mut self, path: &str) -> Self {
        self.req.uri(path);
        self
    }

    /// Set a header
    pub fn set<H: Header>(mut self, hdr: H) -> Self {
        self.req.set(hdr);
        self
    }

    /// Set a header
    pub fn header<K, V>(mut self, key: K, value: V) -> Self
    where
        HeaderName: HttpTryFrom<K>,
        V: IntoHeaderValue,
    {
        self.req.header(key, value);
        self
    }

    /// Set cookie for this request
    pub fn cookie(mut self, cookie: Cookie) -> Self {
        self.req.cookie(cookie);
        self
    }

    /// Set request payload
    pub fn set_payload<B: Into<Bytes>>(mut self, data: B) -> Self {
        self.req.set_payload(data);
        self
    }

    /// Set application data. This is equivalent of `App::data()` method
    /// for testing purpose.
    pub fn app_data<T: 'static>(self, data: T) -> Self {
        self.config.extensions.borrow_mut().insert(data);
        self
    }

    /// Set route data. This is equivalent of `Route::data()` method
    /// for testing purpose.
    pub fn route_data<T: 'static>(mut self, data: T) -> Self {
        self.route_data.insert(RouteData::new(data));
        self
    }

    #[cfg(test)]
    /// Set request config
    pub(crate) fn rmap(mut self, rmap: ResourceMap) -> Self {
        self.rmap = rmap;
        self
    }

    /// Complete request creation and generate `Request` instance
    pub fn to_request(mut self) -> Request<PayloadStream> {
        self.req.finish()
    }

    /// Complete request creation and generate `ServiceRequest` instance
    pub fn to_srv_request(mut self) -> ServiceRequest<PayloadStream> {
        let (head, payload) = self.req.finish().into_parts();

        let req = HttpRequest::new(
            Path::new(Url::new(head.uri.clone())),
            head,
            Rc::new(self.rmap),
            AppConfig::new(self.config),
            HttpRequestPool::create(),
        );

        ServiceRequest::from_parts(req, payload)
    }

    /// Complete request creation and generate `ServiceResponse` instance
    pub fn to_srv_response<B>(self, res: HttpResponse<B>) -> ServiceResponse<B> {
        self.to_srv_request().into_response(res)
    }

    /// Complete request creation and generate `HttpRequest` instance
    pub fn to_http_request(mut self) -> HttpRequest {
        let (head, _) = self.req.finish().into_parts();

        let mut req = HttpRequest::new(
            Path::new(Url::new(head.uri.clone())),
            head,
            Rc::new(self.rmap),
            AppConfig::new(self.config),
            HttpRequestPool::create(),
        );
        req.set_route_data(Some(Rc::new(self.route_data)));
        req
    }

    /// Complete request creation and generate `HttpRequest` and `Payload` instances
    pub fn to_http_parts(mut self) -> (HttpRequest, Payload) {
        let (head, payload) = self.req.finish().into_parts();

        let mut req = HttpRequest::new(
            Path::new(Url::new(head.uri.clone())),
            head,
            Rc::new(self.rmap),
            AppConfig::new(self.config),
            HttpRequestPool::create(),
        );
        req.set_route_data(Some(Rc::new(self.route_data)));
        (req, payload)
    }

    /// Runs the provided future, blocking the current thread until the future
    /// completes.
    ///
    /// This function can be used to synchronously block the current thread
    /// until the provided `future` has resolved either successfully or with an
    /// error. The result of the future is then returned from this function
    /// call.
    ///
    /// Note that this function is intended to be used only for testing purpose.
    /// This function panics on nested call.
    pub fn block_on<F>(f: F) -> Result<F::Item, F::Error>
    where
        F: Future,
    {
        block_on(f)
    }
}
<commit_msg>updated legacy code in call_success example (#762)<commit_after>//! Various helpers for Actix applications to use during testing.
use std::cell::RefCell;
use std::rc::Rc;

use actix_http::cookie::Cookie;
use actix_http::http::header::{Header, HeaderName, IntoHeaderValue};
use actix_http::http::{HttpTryFrom, Method, StatusCode, Version};
use actix_http::test::TestRequest as HttpTestRequest;
use actix_http::{Extensions, PayloadStream, Request};
use actix_router::{Path, ResourceDef, Url};
use actix_rt::Runtime;
use actix_server_config::ServerConfig;
use actix_service::{FnService, IntoNewService, NewService, Service};
use bytes::Bytes;
use futures::future::{lazy, Future};

use crate::config::{AppConfig, AppConfigInner};
use crate::data::RouteData;
use crate::dev::{Body, Payload};
use crate::request::HttpRequestPool;
use crate::rmap::ResourceMap;
use crate::service::{ServiceRequest, ServiceResponse};
use crate::{Error, HttpRequest, HttpResponse};

thread_local! {
    static RT: RefCell<Runtime> = {
        RefCell::new(Runtime::new().unwrap())
    };
}

/// Runs the provided future, blocking the current thread until the future
/// completes.
///
/// This function can be used to synchronously block the current thread
/// until the provided `future` has resolved either successfully or with an
/// error. The result of the future is then returned from this function
/// call.
///
/// Note that this function is intended to be used only for testing purpose.
/// This function panics on nested call.
pub fn block_on<F>(f: F) -> Result<F::Item, F::Error>
where
    F: Future,
{
    RT.with(move |rt| rt.borrow_mut().block_on(f))
}

/// Runs the provided function, with runtime enabled.
///
/// Note that this function is intended to be used only for testing purpose.
/// This function panics on nested call.
pub fn run_on<F, R>(f: F) -> R
where
    F: Fn() -> R,
{
    RT.with(move |rt| rt.borrow_mut().block_on(lazy(|| Ok::<_, ()>(f()))))
        .unwrap()
}

/// Create service that always responds with `HttpResponse::Ok()`
pub fn ok_service() -> impl Service<
    Request = ServiceRequest<PayloadStream>,
    Response = ServiceResponse<Body>,
    Error = Error,
> {
    default_service(StatusCode::OK)
}

/// Create service that responds with response with specified status code
pub fn default_service(
    status_code: StatusCode,
) -> impl Service<
    Request = ServiceRequest<PayloadStream>,
    Response = ServiceResponse<Body>,
    Error = Error,
> {
    FnService::new(move |req: ServiceRequest<PayloadStream>| {
        req.into_response(HttpResponse::build(status_code).finish())
    })
}

/// This method accepts application builder instance, and constructs
/// service.
///
/// ```rust,ignore
/// use actix_service::Service;
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
///
/// fn main() {
///     let mut app = test::init_service(
///         App::new()
///             .service(web::resource("/test").to(|| HttpResponse::Ok()))
///     );
///
///     // Create request object
///     let req = test::TestRequest::with_uri("/test").to_request();
///
///     // Execute application
///     let resp = test::block_on(app.call(req)).unwrap();
///     assert_eq!(resp.status(), StatusCode::OK);
/// }
/// ```
pub fn init_service<R, S, B, E>(
    app: R,
) -> impl Service<Request = Request, Response = ServiceResponse<B>, Error = E>
where
    R: IntoNewService<S, ServerConfig>,
    S: NewService<
        ServerConfig,
        Request = Request,
        Response = ServiceResponse<B>,
        Error = E,
    >,
    S::InitError: std::fmt::Debug,
{
    let cfg = ServerConfig::new("127.0.0.1:8080".parse().unwrap());
    block_on(app.into_new_service().new_service(&cfg)).unwrap()
}

/// Calls service and waits for response future completion.
///
/// ```rust,ignore
/// use actix_web::{test, App, HttpResponse, http::StatusCode};
/// use actix_service::Service;
///
/// fn main() {
///     let mut app = test::init_service(
///         App::new()
///             .service(web::resource("/test").to(|| HttpResponse::Ok()))
///     );
///
///     // Create request object
///     let req = test::TestRequest::with_uri("/test").to_request();
///
///     // Call application
///     let resp = test::call_success(&mut app, req);
///     assert_eq!(resp.status(), StatusCode::OK);
/// }
/// ```
pub fn call_success<S, R, B, E>(app: &mut S, req: R) -> S::Response
where
    S: Service<Request = R, Response = ServiceResponse<B>, Error = E>,
    E: std::fmt::Debug,
{
    block_on(app.call(req)).unwrap()
}

/// Test `Request` builder.
///
/// For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern.
/// You can generate various types of request via TestRequest's methods:
///  * `TestRequest::to_request` creates `actix_http::Request` instance.
///  * `TestRequest::to_service` creates `ServiceRequest` instance, which is used for testing middlewares and chain adapters.
///  * `TestRequest::to_from` creates `ServiceFromRequest` instance, which is used for testing extractors.
///  * `TestRequest::to_http_request` creates `HttpRequest` instance, which is used for testing handlers.
///
/// ```rust,ignore
/// # use futures::IntoFuture;
/// use actix_web::{test, HttpRequest, HttpResponse, HttpMessage};
/// use actix_web::http::{header, StatusCode};
///
/// fn index(req: HttpRequest) -> HttpResponse {
///     if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
///         HttpResponse::Ok().into()
///     } else {
///         HttpResponse::BadRequest().into()
///     }
/// }
///
/// fn main() {
///     let req = test::TestRequest::with_header("content-type", "text/plain")
///         .to_http_request();
///
///     let resp = test::block_on(index(req).into_future()).unwrap();
///     assert_eq!(resp.status(), StatusCode::OK);
///
///     let req = test::TestRequest::default().to_http_request();
///     let resp = test::block_on(index(req).into_future()).unwrap();
///     assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
/// }
/// ```
pub struct TestRequest {
    req: HttpTestRequest,
    rmap: ResourceMap,
    config: AppConfigInner,
    route_data: Extensions,
}

impl Default for TestRequest {
    fn default() -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            config: AppConfigInner::default(),
            route_data: Extensions::new(),
        }
    }
}

#[allow(clippy::wrong_self_convention)]
impl TestRequest {
    /// Create TestRequest and set request uri
    pub fn with_uri(path: &str) -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().uri(path).take(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            config: AppConfigInner::default(),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set header
    pub fn with_hdr<H: Header>(hdr: H) -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().set(hdr).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set header
    pub fn with_header<K, V>(key: K, value: V) -> TestRequest
    where
        HeaderName: HttpTryFrom<K>,
        V: IntoHeaderValue,
    {
        TestRequest {
            req: HttpTestRequest::default().header(key, value).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set method to `Method::GET`
    pub fn get() -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().method(Method::GET).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Create TestRequest and set method to `Method::POST`
    pub fn post() -> TestRequest {
        TestRequest {
            req: HttpTestRequest::default().method(Method::POST).take(),
            config: AppConfigInner::default(),
            rmap: ResourceMap::new(ResourceDef::new("")),
            route_data: Extensions::new(),
        }
    }

    /// Set HTTP version of this request
    pub fn version(mut self, ver: Version) -> Self {
        self.req.version(ver);
        self
    }

    /// Set HTTP method of this request
    pub fn method(mut self, meth: Method) -> Self {
        self.req.method(meth);
        self
    }

    /// Set HTTP Uri of this request
    pub fn uri(mut self, path: &str) -> Self {
        self.req.uri(path);
        self
    }

    /// Set a header
    pub fn set<H: Header>(mut self, hdr: H) -> Self {
        self.req.set(hdr);
        self
    }

    /// Set a header
    pub fn header<K, V>(mut self, key: K, value: V) -> Self
    where
        HeaderName: HttpTryFrom<K>,
        V: IntoHeaderValue,
    {
        self.req.header(key, value);
        self
    }

    /// Set cookie for this request
    pub fn cookie(mut self, cookie: Cookie) -> Self {
        self.req.cookie(cookie);
        self
    }

    /// Set request payload
    pub fn set_payload<B: Into<Bytes>>(mut self, data: B) -> Self {
        self.req.set_payload(data);
        self
    }

    /// Set application data. This is equivalent of `App::data()` method
    /// for testing purpose.
    pub fn app_data<T: 'static>(self, data: T) -> Self {
        self.config.extensions.borrow_mut().insert(data);
        self
    }

    /// Set route data. This is equivalent of `Route::data()` method
    /// for testing purpose.
    pub fn route_data<T: 'static>(mut self, data: T) -> Self {
        self.route_data.insert(RouteData::new(data));
        self
    }

    #[cfg(test)]
    /// Set request config
    pub(crate) fn rmap(mut self, rmap: ResourceMap) -> Self {
        self.rmap = rmap;
        self
    }

    /// Complete request creation and generate `Request` instance
    pub fn to_request(mut self) -> Request<PayloadStream> {
        self.req.finish()
    }

    /// Complete request creation and generate `ServiceRequest` instance
    pub fn to_srv_request(mut self) -> ServiceRequest<PayloadStream> {
        let (head, payload) = self.req.finish().into_parts();

        let req = HttpRequest::new(
            Path::new(Url::new(head.uri.clone())),
            head,
            Rc::new(self.rmap),
            AppConfig::new(self.config),
            HttpRequestPool::create(),
        );

        ServiceRequest::from_parts(req, payload)
    }

    /// Complete request creation and generate `ServiceResponse` instance
    pub fn to_srv_response<B>(self, res: HttpResponse<B>) -> ServiceResponse<B> {
        self.to_srv_request().into_response(res)
    }

    /// Complete request creation and generate `HttpRequest` instance
    pub fn to_http_request(mut self) -> HttpRequest {
        let (head, _) = self.req.finish().into_parts();

        let mut req = HttpRequest::new(
            Path::new(Url::new(head.uri.clone())),
            head,
            Rc::new(self.rmap),
            AppConfig::new(self.config),
            HttpRequestPool::create(),
        );
        req.set_route_data(Some(Rc::new(self.route_data)));
        req
    }

    /// Complete request creation and generate `HttpRequest` and `Payload` instances
    pub fn to_http_parts(mut self) -> (HttpRequest, Payload) {
        let (head, payload) = self.req.finish().into_parts();

        let mut req = HttpRequest::new(
            Path::new(Url::new(head.uri.clone())),
            head,
            Rc::new(self.rmap),
            AppConfig::new(self.config),
            HttpRequestPool::create(),
        );
        req.set_route_data(Some(Rc::new(self.route_data)));
        (req, payload)
    }

    /// Runs the provided future, blocking the current thread until the future
    /// completes.
    ///
    /// This function can be used to synchronously block the current thread
    /// until the provided `future` has resolved either successfully or with an
    /// error. The result of the future is then returned from this function
    /// call.
    ///
    /// Note that this function is intended to be used only for testing purpose.
    /// This function panics on nested call.
    pub fn block_on<F>(f: F) -> Result<F::Item, F::Error>
    where
        F: Future,
    {
        block_on(f)
    }
}
<|endoftext|>


<commit_before>extern crate "rustc-serialize" as serialize;

use std::io::MemWriter;
use std::fmt::Show;
use std::io::MemReader;
use std::collections::HashMap;

use rustc_serialize::{
    Encoder,
    Decoder,
    Encodable,
    Decodable
};

use super::{
    encode,
    decode,
};
use super::SizeLimit::Infinite;

fn the_same<'a, V>(element: V) where V: Encodable, V: Decodable, V: PartialEq, V: Show {
    assert!(element == decode(encode(&element, Infinite).unwrap(), Infinite).unwrap());
}

#[test]
fn test_numbers() {
    // unsigned positive
    the_same(5u8);
    the_same(5u16);
    the_same(5u32);
    the_same(5u64);
    // signed positive
    the_same(5i8);
    the_same(5i16);
    the_same(5i32);
    the_same(5i64);
    // signed negative
    the_same(-5i8);
    the_same(-5i16);
    the_same(-5i32);
    the_same(-5i64);
    // floating
    the_same(-100f32);
    the_same(0f32);
    the_same(5f32);
    the_same(-100f64);
    the_same(5f64);
}

#[test]
fn test_string() {
    the_same("".to_string());
    the_same("a".to_string());
}

#[test]
fn test_tuple() {
    the_same((1i,));
    the_same((1i,2i,3i));
    the_same((1i,"foo".to_string(),()));
}

#[test]
fn test_basic_struct() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct Easy {
        x: int,
        s: String,
        y: uint
    }
    the_same(Easy{x: -4, s: "foo".to_string(), y: 10});
}

#[test]
fn test_nested_struct() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct Easy {
        x: int,
        s: String,
        y: uint
    }
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct Nest {
        f: Easy,
        b: uint,
        s: Easy
    }

    the_same(Nest {
        f: Easy {x: -1, s: "foo".to_string(), y: 20},
        b: 100,
        s: Easy {x: -100, s: "bar".to_string(), y: 20}
    });
}

#[test]
fn test_struct_tuple() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct TubStr(uint, String, f32);

    the_same(TubStr(5, "hello".to_string(), 3.2));
}

#[test]
fn option() {
    the_same(Some(5u));
    the_same(Some("foo bar".to_string()));
    the_same(None::<uint>);
}

#[test]
fn enm() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    enum TestEnum {
        NoArg,
        OneArg(uint),
        AnotherNoArg
    }
    the_same(TestEnum::NoArg);
    the_same(TestEnum::OneArg(4));
    the_same(TestEnum::AnotherNoArg);
}

#[test]
fn struct_enum() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    enum TestEnum {
        NoArg,
        OneArg(uint),
        AnotherNoArg,
        StructLike{x: uint, y: f32}
    }
    the_same(TestEnum::NoArg);
    the_same(TestEnum::OneArg(4));
    the_same(TestEnum::AnotherNoArg);
    the_same(TestEnum::StructLike{x: 4, y: 3.14159});
    the_same(vec![TestEnum::NoArg, TestEnum::OneArg(5), TestEnum::AnotherNoArg,
                  TestEnum::StructLike{x: 4, y:1.4}]);
}

#[test]
fn many() {
    let v: Vec<u8> = vec![];
    the_same(v);
    the_same(vec![1u]);
    the_same(vec![1u,2,3,4,5,6]);
}

#[test]
fn map(){
    let mut m = HashMap::new();
    m.insert(4u, "foo".to_string());
    m.insert(0u, "bar".to_string());
    the_same(m);
}

#[test]
fn boole(){
    the_same(true);
    the_same(false);
}

#[test]
fn unicode() {
    the_same("å".to_string());
    the_same("aåååååååa".to_string());
}
<commit_msg>Remove redundant imports<commit_after>extern crate "rustc-serialize" as serialize;

use std::fmt::Show;
use std::collections::HashMap;

use rustc_serialize::{
    Encoder,
    Decoder,
    Encodable,
    Decodable
};

use super::{
    encode,
    decode,
};
use super::SizeLimit::Infinite;

fn the_same<'a, V>(element: V) where V: Encodable, V: Decodable, V: PartialEq, V: Show {
    assert!(element == decode(encode(&element, Infinite).unwrap(), Infinite).unwrap());
}

#[test]
fn test_numbers() {
    // unsigned positive
    the_same(5u8);
    the_same(5u16);
    the_same(5u32);
    the_same(5u64);
    // signed positive
    the_same(5i8);
    the_same(5i16);
    the_same(5i32);
    the_same(5i64);
    // signed negative
    the_same(-5i8);
    the_same(-5i16);
    the_same(-5i32);
    the_same(-5i64);
    // floating
    the_same(-100f32);
    the_same(0f32);
    the_same(5f32);
    the_same(-100f64);
    the_same(5f64);
}

#[test]
fn test_string() {
    the_same("".to_string());
    the_same("a".to_string());
}

#[test]
fn test_tuple() {
    the_same((1i,));
    the_same((1i,2i,3i));
    the_same((1i,"foo".to_string(),()));
}

#[test]
fn test_basic_struct() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct Easy {
        x: int,
        s: String,
        y: uint
    }
    the_same(Easy{x: -4, s: "foo".to_string(), y: 10});
}

#[test]
fn test_nested_struct() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct Easy {
        x: int,
        s: String,
        y: uint
    }
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct Nest {
        f: Easy,
        b: uint,
        s: Easy
    }

    the_same(Nest {
        f: Easy {x: -1, s: "foo".to_string(), y: 20},
        b: 100,
        s: Easy {x: -100, s: "bar".to_string(), y: 20}
    });
}

#[test]
fn test_struct_tuple() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    struct TubStr(uint, String, f32);

    the_same(TubStr(5, "hello".to_string(), 3.2));
}

#[test]
fn option() {
    the_same(Some(5u));
    the_same(Some("foo bar".to_string()));
    the_same(None::<uint>);
}

#[test]
fn enm() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    enum TestEnum {
        NoArg,
        OneArg(uint),
        AnotherNoArg
    }
    the_same(TestEnum::NoArg);
    the_same(TestEnum::OneArg(4));
    the_same(TestEnum::AnotherNoArg);
}

#[test]
fn struct_enum() {
    #[derive(RustcEncodable, RustcDecodable, PartialEq, Show)]
    enum TestEnum {
        NoArg,
        OneArg(uint),
        AnotherNoArg,
        StructLike{x: uint, y: f32}
    }
    the_same(TestEnum::NoArg);
    the_same(TestEnum::OneArg(4));
    the_same(TestEnum::AnotherNoArg);
    the_same(TestEnum::StructLike{x: 4, y: 3.14159});
    the_same(vec![TestEnum::NoArg, TestEnum::OneArg(5), TestEnum::AnotherNoArg,
                  TestEnum::StructLike{x: 4, y:1.4}]);
}

#[test]
fn many() {
    let v: Vec<u8> = vec![];
    the_same(v);
    the_same(vec![1u]);
    the_same(vec![1u,2,3,4,5,6]);
}

#[test]
fn map(){
    let mut m = HashMap::new();
    m.insert(4u, "foo".to_string());
    m.insert(0u, "bar".to_string());
    the_same(m);
}

#[test]
fn boole(){
    the_same(true);
    the_same(false);
}

#[test]
fn unicode() {
    the_same("å".to_string());
    the_same("aåååååååa".to_string());
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::fs::File;
use std::io::prelude::*;
use std::env;

pub fn read_file(path_str: &str) -> String {
    let mut path = env::current_dir().unwrap();
    path.push(Path::new(path_str));

    if !path.exists() {
        panic!("Error reading file, path {} doesn't exist.", path.display());
    }

    let mut f = match File::open(&path) {
        Ok(f) => f,
        Err(msg) => panic!("Error reading file {} : {}.", path.display(), msg)
    };

    // read bytes and return as str
    let mut bytes = Vec::new();
    match f.read_to_end(&mut bytes) {
        Ok(_) => {
            match String::from_utf8(bytes) {
                Ok(s) => s,
                Err(msg) => panic!("Found non valid utf8 characters in {} : {}.", path.display(), msg)
            }
        },
        Err(msg) => panic!("Error reading file {} : {}.", path.display(), msg)
    }
}<commit_msg>Added check extension for files.<commit_after>use std::path::Path;
use std::fs::File;
use std::io::prelude::*;
use std::env;

pub fn check_extension(path: &Path, valid_ext: &[&str]) -> bool {
    let ext = &path.extension().expect("The file has no extension").to_str().expect("Extension is not valid utf8");

    for vext in valid_ext.iter() {
        if vext == ext {
            return true;
        }
    }
    false
}

pub fn read_file(path_str: &str) -> String {
    let mut path = env::current_dir().unwrap();
    path.push(Path::new(path_str));

    if !path.exists() {
        panic!("Error reading file, path {} doesn't exist.", path.display());
    }

    let mut f = match File::open(&path) {
        Ok(f) => f,
        Err(msg) => panic!("Error reading file {} : {}.", path.display(), msg)
    };

    // read bytes and return as str
    let mut bytes = Vec::new();
    match f.read_to_end(&mut bytes) {
        Ok(_) => {
            match String::from_utf8(bytes) {
                Ok(s) => s,
                Err(msg) => panic!("Found non valid utf8 characters in {} : {}.", path.display(), msg)
            }
        },
        Err(msg) => panic!("Error reading file {} : {}.", path.display(), msg)
    }
}<|endoftext|>


<commit_before>use ::game;
use ::game::board;
use ::clap::{App, Arg};
use ::mcts;

pub const ITERATION_COUNT_FLAG: &'static str = "iterations";
pub const SIMULATION_COUNT_FLAG: &'static str = "simulations";
pub const EXPLORATION_BIAS_FLAG: &'static str = "explore_bias";
pub const INITIAL_BOARD_FLAG: &'static str = "initial_board";
pub const INITIAL_PLAYER_FLAG: &'static str = "initial_player";
pub const AI_PLAYER_FLAG: &'static str = "ai_player";
pub const LOG_LEVEL_FLAG: &'static str = "log_level";

arg_enum! {
    #[derive(Debug)]
    pub enum InitialBoard {
        Default,
        TrollEndgame,
        DwarfEndgame,
        DwarfBoxed
    }
}

impl InitialBoard {
    pub fn cells(&self) -> board::Cells {
        match *self {
            InitialBoard::Default => board::decode_board(DEFAULT_CELLS),
            InitialBoard::TrollEndgame => board::decode_board(TROLL_ENDGAME),
            InitialBoard::DwarfEndgame => board::decode_board(DWARF_ENDGAME),
            InitialBoard::DwarfBoxed => board::decode_board(DWARF_BOXED),
        }
    }
}

const DEFAULT_CELLS: &'static str = r#"
.....dd_dd.....
....d_____d....
...d_______d...
..d_________d..
.d___________d.
d_____________d
d_____TTT_____d
______TOT______
d_____TTT_____d
d_____________d
.d___________d.
..d_________d..
...d_______d...
....d_____d....
.....dd_dd.....
"#;

const TROLL_ENDGAME: &'static str = r#"
....._____.....
...._______....
...__ddd____...
..___d_d_____..
.____d_d______.
_______________
______T________
______TO_______
______T________
_______________
._____________.
..___________..
..._________...
...._______....
....._____.....
"#;

const DWARF_ENDGAME: &'static str = r#"
....._____.....
...._______....
..._________...
..___________..
._____________.
_______________
_______________
_ddd__TO_______
_______________
_______________
._____________.
..___________..
..._________...
...._______....
....._____.....
"#;

const DWARF_BOXED: &'static str = r#"
.....d___d.....
...._______....
..._________...
..___________..
._d_________d_.
_dd_________dd_
dddd__TTT__dddd
______TOT______
dddd__TTT__dddd
_dd_________dd_
._d_________d_.
..d_________d..
..._________...
...._______....
.....d___d.....
"#;

pub fn set_common_args<'a, 'b>(app: App<'a, 'b>, flags: &[&str]) -> App<'a, 'b> where 'a: 'b {
    let populated_flags: Vec<Arg<'static, 'static>> = flags.iter().map(|f| match *f {
        x if x == ITERATION_COUNT_FLAG =>
            Arg::with_name(ITERATION_COUNT_FLAG)
            .short("i")
            .long("iterations")
            .takes_value(true)
            .value_name("ITERATIONS")
            .help("Number of Monte Carlo iterations to run per epoch")
            .required(true),
        x if x == SIMULATION_COUNT_FLAG =>
            Arg::with_name(SIMULATION_COUNT_FLAG)
            .short("s")
            .long("simulations")
            .takes_value(true)
            .value_name("SIMULATIONS")
            .help("Number of simulations to run at each expansion step")
            .required(true),
        x if x == EXPLORATION_BIAS_FLAG =>
            Arg::with_name(EXPLORATION_BIAS_FLAG)
            .short("b")
            .long("exploration_bias")
            .takes_value(true)
            .value_name("BIAS")
            .help("Exploration bias for UCB computation")
            .required(true),
        x if x == INITIAL_BOARD_FLAG =>
            Arg::with_name(INITIAL_BOARD_FLAG)
            .long("board")
            .takes_value(true)
            .possible_values(&["default", "trollendgame", "dwarfendgame"])
            .help("Initial board configuration"),
        x if x == INITIAL_PLAYER_FLAG =>
            Arg::with_name(INITIAL_PLAYER_FLAG)
            .short("p")
            .long("player")
            .takes_value(true)
            .possible_values(&["dwarf", "troll"])
            .help("Initial player to play"),
        x if x == AI_PLAYER_FLAG =>
            Arg::with_name(AI_PLAYER_FLAG)
            .short("p")
            .long("player")
            .takes_value(true)
            .possible_values(&["dwarf", "troll"])
            .help("Side that the AI will play"),
        x if x == LOG_LEVEL_FLAG =>
            Arg::with_name(LOG_LEVEL_FLAG)
            .long("log_level")
            .takes_value(true)
            .possible_values(&["info", "trace", "error", "debug", "off"])
            .help("Logging level"),
        x => panic!("Unrecognized flag identifier '{}'", x),
    }).collect();
    app.args(&populated_flags)
}

pub fn initialize_search(state: mcts::State, graph: &mut mcts::Graph) {
    let actions: Vec<game::Action> = state.role_actions(state.active_role()).collect();
    let mut children = graph.add_root(state, Default::default()).to_child_list();
    for a in actions.into_iter() {
        children.add_child(mcts::EdgeData::new(a));
    }
}
<commit_msg>Add missing variant to initial board flag.<commit_after>use ::game;
use ::game::board;
use ::clap::{App, Arg};
use ::mcts;

pub const ITERATION_COUNT_FLAG: &'static str = "iterations";
pub const SIMULATION_COUNT_FLAG: &'static str = "simulations";
pub const EXPLORATION_BIAS_FLAG: &'static str = "explore_bias";
pub const INITIAL_BOARD_FLAG: &'static str = "initial_board";
pub const INITIAL_PLAYER_FLAG: &'static str = "initial_player";
pub const AI_PLAYER_FLAG: &'static str = "ai_player";
pub const LOG_LEVEL_FLAG: &'static str = "log_level";

arg_enum! {
    #[derive(Debug)]
    pub enum InitialBoard {
        Default,
        TrollEndgame,
        DwarfEndgame,
        DwarfBoxed
    }
}

impl InitialBoard {
    pub fn cells(&self) -> board::Cells {
        match *self {
            InitialBoard::Default => board::decode_board(DEFAULT_CELLS),
            InitialBoard::TrollEndgame => board::decode_board(TROLL_ENDGAME),
            InitialBoard::DwarfEndgame => board::decode_board(DWARF_ENDGAME),
            InitialBoard::DwarfBoxed => board::decode_board(DWARF_BOXED),
        }
    }
}

const DEFAULT_CELLS: &'static str = r#"
.....dd_dd.....
....d_____d....
...d_______d...
..d_________d..
.d___________d.
d_____________d
d_____TTT_____d
______TOT______
d_____TTT_____d
d_____________d
.d___________d.
..d_________d..
...d_______d...
....d_____d....
.....dd_dd.....
"#;

const TROLL_ENDGAME: &'static str = r#"
....._____.....
...._______....
...__ddd____...
..___d_d_____..
.____d_d______.
_______________
______T________
______TO_______
______T________
_______________
._____________.
..___________..
..._________...
...._______....
....._____.....
"#;

const DWARF_ENDGAME: &'static str = r#"
....._____.....
...._______....
..._________...
..___________..
._____________.
_______________
_______________
_ddd__TO_______
_______________
_______________
._____________.
..___________..
..._________...
...._______....
....._____.....
"#;

const DWARF_BOXED: &'static str = r#"
.....d___d.....
...._______....
..._________...
..___________..
._d_________d_.
_dd_________dd_
dddd__TTT__dddd
______TOT______
dddd__TTT__dddd
_dd_________dd_
._d_________d_.
..d_________d..
..._________...
...._______....
.....d___d.....
"#;

pub fn set_common_args<'a, 'b>(app: App<'a, 'b>, flags: &[&str]) -> App<'a, 'b> where 'a: 'b {
    let populated_flags: Vec<Arg<'static, 'static>> = flags.iter().map(|f| match *f {
        x if x == ITERATION_COUNT_FLAG =>
            Arg::with_name(ITERATION_COUNT_FLAG)
            .short("i")
            .long("iterations")
            .takes_value(true)
            .value_name("ITERATIONS")
            .help("Number of Monte Carlo iterations to run per epoch")
            .required(true),
        x if x == SIMULATION_COUNT_FLAG =>
            Arg::with_name(SIMULATION_COUNT_FLAG)
            .short("s")
            .long("simulations")
            .takes_value(true)
            .value_name("SIMULATIONS")
            .help("Number of simulations to run at each expansion step")
            .required(true),
        x if x == EXPLORATION_BIAS_FLAG =>
            Arg::with_name(EXPLORATION_BIAS_FLAG)
            .short("b")
            .long("exploration_bias")
            .takes_value(true)
            .value_name("BIAS")
            .help("Exploration bias for UCB computation")
            .required(true),
        x if x == INITIAL_BOARD_FLAG =>
            Arg::with_name(INITIAL_BOARD_FLAG)
            .long("board")
            .takes_value(true)
            .possible_values(&["default", "trollendgame", "dwarfendgame", "dwarfboxed"])
            .help("Initial board configuration"),
        x if x == INITIAL_PLAYER_FLAG =>
            Arg::with_name(INITIAL_PLAYER_FLAG)
            .short("p")
            .long("player")
            .takes_value(true)
            .possible_values(&["dwarf", "troll"])
            .help("Initial player to play"),
        x if x == AI_PLAYER_FLAG =>
            Arg::with_name(AI_PLAYER_FLAG)
            .short("p")
            .long("player")
            .takes_value(true)
            .possible_values(&["dwarf", "troll"])
            .help("Side that the AI will play"),
        x if x == LOG_LEVEL_FLAG =>
            Arg::with_name(LOG_LEVEL_FLAG)
            .long("log_level")
            .takes_value(true)
            .possible_values(&["info", "trace", "error", "debug", "off"])
            .help("Logging level"),
        x => panic!("Unrecognized flag identifier '{}'", x),
    }).collect();
    app.args(&populated_flags)
}

pub fn initialize_search(state: mcts::State, graph: &mut mcts::Graph) {
    let actions: Vec<game::Action> = state.role_actions(state.active_role()).collect();
    let mut children = graph.add_root(state, Default::default()).to_child_list();
    for a in actions.into_iter() {
        children.add_child(mcts::EdgeData::new(a));
    }
}
<|endoftext|>


<commit_before>//! Private utility module
use std::io::{Read, Result as IoResult, Seek};
use std::ops::{Add, Mul};
use std::path::{Path, PathBuf};
use asprim::AsPrim;
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
use num::Num;

#[cfg(feature = "ndarray_volumes")]
use std::mem;
#[cfg(feature = "ndarray_volumes")]
use ndarray::{Array, Ix, IxDyn, ShapeBuilder};
#[cfg(feature = "ndarray_volumes")]
use safe_transmute::{guarded_transmute_pod_vec_permissive, PodTransmutable};

/// A trait that is both Read and Seek.
pub trait ReadSeek: Read + Seek {}
impl<T: Read + Seek> ReadSeek for T {}

/// Enumerate for the two kinds of endianness possible by the standard.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Endianness {
    /// Little Endian
    LE,
    /// Big Endian
    BE,
}

impl Endianness {
    /// Obtain this system's endianness
    #[cfg(target_endian = "little")]
    pub fn system() -> Endianness {
        Endianness::LE
    }

    /// Obtain this system's endianness
    #[cfg(target_endian = "big")]
    pub fn system() -> Endianness {
        Endianness::BE
    }

    /// The opposite endianness: Little Endian returns Big Endian and vice versa.
    pub fn opposite(&self) -> Endianness {
        if *self == Endianness::LE {
            Endianness::BE
        } else {
            Endianness::LE
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_i16<S>(&self, mut src: S) -> IoResult<i16>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_i16::<LittleEndian>(),
            Endianness::BE => src.read_i16::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_u16<S>(&self, mut src: S) -> IoResult<u16>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_u16::<LittleEndian>(),
            Endianness::BE => src.read_u16::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_i32<S>(&self, mut src: S) -> IoResult<i32>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_i32::<LittleEndian>(),
            Endianness::BE => src.read_i32::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_u32<S>(&self, mut src: S) -> IoResult<u32>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_u32::<LittleEndian>(),
            Endianness::BE => src.read_u32::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_i64<S>(&self, mut src: S) -> IoResult<i64>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_i64::<LittleEndian>(),
            Endianness::BE => src.read_i64::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_u64<S>(&self, mut src: S) -> IoResult<u64>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_u64::<LittleEndian>(),
            Endianness::BE => src.read_u64::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_f32<S>(&self, mut src: S) -> IoResult<f32>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_f32::<LittleEndian>(),
            Endianness::BE => src.read_f32::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_f64<S>(&self, mut src: S) -> IoResult<f64>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_f64::<LittleEndian>(),
            Endianness::BE => src.read_f64::<BigEndian>(),
        }
    }
}

/// Defines the serialization that is opposite to system native-endian.
/// This is `BigEndian` in a Little Endian system and `LittleEndian` in a Big Endian system.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[cfg(target_endian = "little")]
pub type OppositeNativeEndian = BigEndian;

/// Defines the serialization that is opposite to system native-endian.
/// This is `BigEndian` in a Little Endian system and `LittleEndian` in a Big Endian system.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[cfg(target_endian = "big")]
pub type OppositeNativeEndian = LittleEndian;

/// Convert a raw volume value to the scale defined
/// by the given scale slope and intercept parameters.
/// The linear transformation is performed over the type `T`.
pub fn raw_to_value<V, T>(value: V, slope: T, intercept: T) -> T
where
    T: AsPrim,
    V: AsPrim,
    T: Num,
    T: Mul<Output = T>,
    T: Add<Output = T>,
{
    if slope != T::zero() {
        slope * value.as_() + intercept
    } else {
        value.as_()
    }
}

/// Convert a raw volume value to the scale defined
/// by the given scale slope and intercept parameters.
/// This implementation performs the linear transformation
/// over the `f32` type, then converts it to the intended value type.
pub fn raw_to_value_via_f32<V, T>(value: V, slope: f32, intercept: f32) -> T
where
    T: AsPrim,
    V: AsPrim
{
    if slope != 0. {
        (value.as_f32() * slope + intercept).as_()
    } else {
        value.as_()
    }
}

#[cfg(feature = "ndarray_volumes")]
pub fn convert_bytes_and_cast_to<I, O>(
    raw_data: Vec<u8>,
    e: Endianness,
    dim: &Vec<Ix>,
    slope: O,
    inter: O
    ) -> Array<O, IxDyn>
    where I: AsPrim + PodTransmutable,
          O: AsPrim + Num
{
    let data: Vec<I> = convert_bytes_to(raw_data, e);
    Array::from_shape_vec(IxDyn(&dim).f(), data)
        .expect("Inconsistent raw data size")
        .mapv(|v| raw_to_value::<I, O>(v, slope, inter))
}

#[cfg(feature = "ndarray_volumes")]
pub fn convert_bytes_to<T: PodTransmutable>(
    mut a: Vec<u8>,
    e: Endianness
) -> Vec<T> {
    if e != Endianness::system() {
        match mem::size_of::<T>() {
            1 => { /* Endianness can't be wrong */ }
            2 => {
                for c in a.chunks_mut(2) {
                    let (a, b) = c.split_at_mut(2);
                    mem::swap(&mut a[0], &mut b[1]);
                }
            }
            4 => {
                for c in a.chunks_mut(4) {
                    let (a, b) = c.split_at_mut(2);
                    mem::swap(&mut a[0], &mut b[1]);
                    mem::swap(&mut a[1], &mut b[0]);
                }
            }
            8 => {
                for c1 in a.chunks_mut(8) {
                    for c2 in c1.chunks_mut(4) {
                        let (a, b) = c2.split_at_mut(2);
                        mem::swap(&mut a[0], &mut b[1]);
                        mem::swap(&mut a[1], &mut b[0]);
                    }
                }
            }
            16 => {
                for c1 in a.chunks_mut(16) {
                    for c2 in c1.chunks_mut(8) {
                        for c3 in c2.chunks_mut(4) {
                            let (a, b) = c3.split_at_mut(2);
                            mem::swap(&mut a[0], &mut b[1]);
                            mem::swap(&mut a[1], &mut b[0]);
                        }
                    }
                }
            }
            // TODO
            _ => {}
        };
    }

    guarded_transmute_pod_vec_permissive(a)
}

pub fn is_gz_file<P: AsRef<Path>>(path: P) -> bool {
    path.as_ref()
        .file_name()
        .map(|a| a.to_string_lossy().ends_with(".gz"))
        .unwrap_or(false)
}

/// Convert a file path to a header file (.hdr or .hdr.gz) to
/// the respective volume file with GZip compression (.img.gz).
///
/// # Panics
/// Can panic if the given file path is not a valid path to a header file.
/// If it doesn't panic in this case, the result might still not be correct.
pub fn to_img_file_gz(path: PathBuf) -> PathBuf {
    let gz = is_gz_file(&path);
    let fname = path.file_name().unwrap().to_owned();
    let fname = fname.to_string_lossy();
    let mut fname = if gz {
        fname[..fname.len() - ".hdr.gz".len()].to_owned()
    } else {
        fname[..fname.len() - ".hdr".len()].to_owned()
    };
    fname += ".img.gz";
    path.with_file_name(fname)
}

#[cfg(test)]
mod tests {
    use super::Endianness;
    use super::{raw_to_value, raw_to_value_via_f32};
    use super::to_img_file_gz;
    use super::is_gz_file;
    use super::convert_bytes_to;
    use std::path::PathBuf;

    #[test]
    fn endianness() {
        let le = Endianness::LE;
        assert_eq!(le.opposite(), Endianness::BE);
        assert_eq!(le.opposite().opposite(), Endianness::LE);
    }

    #[cfg(target_endian = "little")]
    #[test]
    fn system_endianness() {
        let le = Endianness::system();
        assert_eq!(le, Endianness::LE);
        assert_eq!(le.opposite(), Endianness::BE);
    }

    #[cfg(target_endian = "big")]
    #[test]
    fn system_endianness() {
        let le = Endianness::system();
        assert_eq!(le, Endianness::BE);
        assert_eq!(le.opposite(), Endianness::LE);
    }

    #[test]
    fn test_convert_vec_f32() {
        let v: Vec<f32> = convert_bytes_to(
            vec![0x42, 0x28, 0x00, 0x00, 0x42, 0x2A, 0x00, 0x00,],
            Endianness::BE);
        assert_eq!(v, vec![42., 42.5]);

        let v: Vec<f32> = convert_bytes_to(
            vec![0x00, 0x00, 0x28, 0x42, 0x00, 0x00, 0x2A, 0x42],
            Endianness::LE);
        assert_eq!(v, vec![42., 42.5]);
    }

    #[test]
    fn test_raw_to_value() {
        let raw: u8 = 100;
        let val: u8 = raw_to_value_via_f32(raw, 1., 0.);
        assert_eq!(val, 100);
        let val: u8 = raw_to_value_via_f32(raw, 0., 0.);
        assert_eq!(val, 100);
        let val: f32 = raw_to_value_via_f32(raw, 2., -1024.);
        assert_ulps_eq!(val, -824.);
        let val: i32 = raw_to_value_via_f32(raw, 2., -1024.);
        assert_eq!(val, -824);
        let val: i16 = raw_to_value_via_f32(raw, 2., -1024.);
        assert_eq!(val, -824);

        let raw: f32 = 0.4;
        let val: f32 = raw_to_value(raw, 1., 0.);
        assert_ulps_eq!(val, 0.4);
        let val: f64 = raw_to_value(raw, 1., 0.);
        assert_ulps_eq!(val, 0.4_f32 as f64);
    }

    #[test]
    fn filenames() {
        assert!(!is_gz_file("/path/to/something.nii"));
        assert!(is_gz_file("/path/to/something.nii.gz"));
        assert!(!is_gz_file("volume.não"));
        assert!(is_gz_file("1.2.3.nii.gz"));
        assert!(!is_gz_file("não_é_gz.hdr"));

        assert!(!is_gz_file("/path/to/image.hdr"));
        assert_eq!(
            to_img_file_gz(PathBuf::from("/path/to/image.hdr")),
            PathBuf::from("/path/to/image.img.gz")
        );

        assert!(is_gz_file("/path/to/image.hdr.gz"));
        assert_eq!(
            to_img_file_gz(PathBuf::from("/path/to/image.hdr.gz")),
            PathBuf::from("/path/to/image.img.gz")
        );

        assert_eq!(
            to_img_file_gz(PathBuf::from("my_ct_scan.1.hdr.gz")),
            PathBuf::from("my_ct_scan.1.img.gz")
        );

        assert_eq!(
            to_img_file_gz(PathBuf::from("../you.cant.fool.me.hdr.gz")),
            PathBuf::from("../you.cant.fool.me.img.gz")
        );
    }
}
<commit_msg>Fix conversion for 8 bytes types<commit_after>//! Private utility module
use std::io::{Read, Result as IoResult, Seek};
use std::ops::{Add, Mul};
use std::path::{Path, PathBuf};
use asprim::AsPrim;
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
use num::Num;

#[cfg(feature = "ndarray_volumes")]
use std::mem;
#[cfg(feature = "ndarray_volumes")]
use ndarray::{Array, Ix, IxDyn, ShapeBuilder};
#[cfg(feature = "ndarray_volumes")]
use safe_transmute::{guarded_transmute_pod_vec_permissive, PodTransmutable};

/// A trait that is both Read and Seek.
pub trait ReadSeek: Read + Seek {}
impl<T: Read + Seek> ReadSeek for T {}

/// Enumerate for the two kinds of endianness possible by the standard.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Endianness {
    /// Little Endian
    LE,
    /// Big Endian
    BE,
}

impl Endianness {
    /// Obtain this system's endianness
    #[cfg(target_endian = "little")]
    pub fn system() -> Endianness {
        Endianness::LE
    }

    /// Obtain this system's endianness
    #[cfg(target_endian = "big")]
    pub fn system() -> Endianness {
        Endianness::BE
    }

    /// The opposite endianness: Little Endian returns Big Endian and vice versa.
    pub fn opposite(&self) -> Endianness {
        if *self == Endianness::LE {
            Endianness::BE
        } else {
            Endianness::LE
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_i16<S>(&self, mut src: S) -> IoResult<i16>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_i16::<LittleEndian>(),
            Endianness::BE => src.read_i16::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_u16<S>(&self, mut src: S) -> IoResult<u16>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_u16::<LittleEndian>(),
            Endianness::BE => src.read_u16::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_i32<S>(&self, mut src: S) -> IoResult<i32>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_i32::<LittleEndian>(),
            Endianness::BE => src.read_i32::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_u32<S>(&self, mut src: S) -> IoResult<u32>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_u32::<LittleEndian>(),
            Endianness::BE => src.read_u32::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_i64<S>(&self, mut src: S) -> IoResult<i64>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_i64::<LittleEndian>(),
            Endianness::BE => src.read_i64::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_u64<S>(&self, mut src: S) -> IoResult<u64>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_u64::<LittleEndian>(),
            Endianness::BE => src.read_u64::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_f32<S>(&self, mut src: S) -> IoResult<f32>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_f32::<LittleEndian>(),
            Endianness::BE => src.read_f32::<BigEndian>(),
        }
    }

    /// Read a primitive value with this endianness from the given source.
    pub fn read_f64<S>(&self, mut src: S) -> IoResult<f64>
    where
        S: Read,
    {
        match *self {
            Endianness::LE => src.read_f64::<LittleEndian>(),
            Endianness::BE => src.read_f64::<BigEndian>(),
        }
    }
}

/// Defines the serialization that is opposite to system native-endian.
/// This is `BigEndian` in a Little Endian system and `LittleEndian` in a Big Endian system.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[cfg(target_endian = "little")]
pub type OppositeNativeEndian = BigEndian;

/// Defines the serialization that is opposite to system native-endian.
/// This is `BigEndian` in a Little Endian system and `LittleEndian` in a Big Endian system.
///
/// Note that this type has no value constructor. It is used purely at the
/// type level.
#[cfg(target_endian = "big")]
pub type OppositeNativeEndian = LittleEndian;

/// Convert a raw volume value to the scale defined
/// by the given scale slope and intercept parameters.
/// The linear transformation is performed over the type `T`.
pub fn raw_to_value<V, T>(value: V, slope: T, intercept: T) -> T
where
    T: AsPrim,
    V: AsPrim,
    T: Num,
    T: Mul<Output = T>,
    T: Add<Output = T>,
{
    if slope != T::zero() {
        slope * value.as_() + intercept
    } else {
        value.as_()
    }
}

/// Convert a raw volume value to the scale defined
/// by the given scale slope and intercept parameters.
/// This implementation performs the linear transformation
/// over the `f32` type, then converts it to the intended value type.
pub fn raw_to_value_via_f32<V, T>(value: V, slope: f32, intercept: f32) -> T
where
    T: AsPrim,
    V: AsPrim
{
    if slope != 0. {
        (value.as_f32() * slope + intercept).as_()
    } else {
        value.as_()
    }
}

#[cfg(feature = "ndarray_volumes")]
pub fn convert_bytes_and_cast_to<I, O>(
    raw_data: Vec<u8>,
    e: Endianness,
    dim: &Vec<Ix>,
    slope: O,
    inter: O
    ) -> Array<O, IxDyn>
    where I: AsPrim + PodTransmutable,
          O: AsPrim + Num
{
    let data: Vec<I> = convert_bytes_to(raw_data, e);
    Array::from_shape_vec(IxDyn(&dim).f(), data)
        .expect("Inconsistent raw data size")
        .mapv(|v| raw_to_value::<I, O>(v, slope, inter))
}

#[cfg(feature = "ndarray_volumes")]
pub fn convert_bytes_to<T: PodTransmutable>(
    mut a: Vec<u8>,
    e: Endianness
) -> Vec<T> {
    let nb_bytes = mem::size_of::<T>();
    if e != Endianness::system() && nb_bytes > 1 {
        // Swap endianness by block of nb_bytes
        let split_at = nb_bytes / 2;
        let split_at_m1 = split_at - 1;
        for c in a.chunks_mut(nb_bytes) {
            let (a, b) = c.split_at_mut(split_at);
            for i in 0..split_at {
                mem::swap(&mut a[i], &mut b[split_at_m1 - i]);
            }
        }
    }

    guarded_transmute_pod_vec_permissive(a)
}

pub fn is_gz_file<P: AsRef<Path>>(path: P) -> bool {
    path.as_ref()
        .file_name()
        .map(|a| a.to_string_lossy().ends_with(".gz"))
        .unwrap_or(false)
}

/// Convert a file path to a header file (.hdr or .hdr.gz) to
/// the respective volume file with GZip compression (.img.gz).
///
/// # Panics
/// Can panic if the given file path is not a valid path to a header file.
/// If it doesn't panic in this case, the result might still not be correct.
pub fn to_img_file_gz(path: PathBuf) -> PathBuf {
    let gz = is_gz_file(&path);
    let fname = path.file_name().unwrap().to_owned();
    let fname = fname.to_string_lossy();
    let mut fname = if gz {
        fname[..fname.len() - ".hdr.gz".len()].to_owned()
    } else {
        fname[..fname.len() - ".hdr".len()].to_owned()
    };
    fname += ".img.gz";
    path.with_file_name(fname)
}

#[cfg(test)]
mod tests {
    use super::Endianness;
    use super::{raw_to_value, raw_to_value_via_f32};
    use super::to_img_file_gz;
    use super::is_gz_file;
    use super::convert_bytes_to;
    use std::path::PathBuf;

    #[test]
    fn endianness() {
        let le = Endianness::LE;
        assert_eq!(le.opposite(), Endianness::BE);
        assert_eq!(le.opposite().opposite(), Endianness::LE);
    }

    #[cfg(target_endian = "little")]
    #[test]
    fn system_endianness() {
        let le = Endianness::system();
        assert_eq!(le, Endianness::LE);
        assert_eq!(le.opposite(), Endianness::BE);
    }

    #[cfg(target_endian = "big")]
    #[test]
    fn system_endianness() {
        let le = Endianness::system();
        assert_eq!(le, Endianness::BE);
        assert_eq!(le.opposite(), Endianness::LE);
    }

    #[test]
    fn test_convert_vec_f32() {
        let v: Vec<f32> = convert_bytes_to(
            vec![0x42, 0x28, 0x00, 0x00, 0x42, 0x2A, 0x00, 0x00,],
            Endianness::BE);
        assert_eq!(v, vec![42., 42.5]);

        let v: Vec<f32> = convert_bytes_to(
            vec![0x00, 0x00, 0x28, 0x42, 0x00, 0x00, 0x2A, 0x42],
            Endianness::LE);
        assert_eq!(v, vec![42., 42.5]);
    }

    #[test]
    fn test_raw_to_value() {
        let raw: u8 = 100;
        let val: u8 = raw_to_value_via_f32(raw, 1., 0.);
        assert_eq!(val, 100);
        let val: u8 = raw_to_value_via_f32(raw, 0., 0.);
        assert_eq!(val, 100);
        let val: f32 = raw_to_value_via_f32(raw, 2., -1024.);
        assert_ulps_eq!(val, -824.);
        let val: i32 = raw_to_value_via_f32(raw, 2., -1024.);
        assert_eq!(val, -824);
        let val: i16 = raw_to_value_via_f32(raw, 2., -1024.);
        assert_eq!(val, -824);

        let raw: f32 = 0.4;
        let val: f32 = raw_to_value(raw, 1., 0.);
        assert_ulps_eq!(val, 0.4);
        let val: f64 = raw_to_value(raw, 1., 0.);
        assert_ulps_eq!(val, 0.4_f32 as f64);
    }

    #[test]
    fn filenames() {
        assert!(!is_gz_file("/path/to/something.nii"));
        assert!(is_gz_file("/path/to/something.nii.gz"));
        assert!(!is_gz_file("volume.não"));
        assert!(is_gz_file("1.2.3.nii.gz"));
        assert!(!is_gz_file("não_é_gz.hdr"));

        assert!(!is_gz_file("/path/to/image.hdr"));
        assert_eq!(
            to_img_file_gz(PathBuf::from("/path/to/image.hdr")),
            PathBuf::from("/path/to/image.img.gz")
        );

        assert!(is_gz_file("/path/to/image.hdr.gz"));
        assert_eq!(
            to_img_file_gz(PathBuf::from("/path/to/image.hdr.gz")),
            PathBuf::from("/path/to/image.img.gz")
        );

        assert_eq!(
            to_img_file_gz(PathBuf::from("my_ct_scan.1.hdr.gz")),
            PathBuf::from("my_ct_scan.1.img.gz")
        );

        assert_eq!(
            to_img_file_gz(PathBuf::from("../you.cant.fool.me.hdr.gz")),
            PathBuf::from("../you.cant.fool.me.img.gz")
        );
    }
}
<|endoftext|>


<commit_before>import core::*;

// -*- rust -*-
use std;
import std::rand;
import str;

#[test]
fn test() {
    let r1: rand::rng = rand::mk_rng();
    log_full(core::debug, r1.next());
    log_full(core::debug, r1.next());
    {
        let r2 = rand::mk_rng();
        log_full(core::debug, r1.next());
        log_full(core::debug, r2.next());
        log_full(core::debug, r1.next());
        log_full(core::debug, r1.next());
        log_full(core::debug, r2.next());
        log_full(core::debug, r2.next());
        log_full(core::debug, r1.next());
        log_full(core::debug, r1.next());
        log_full(core::debug, r1.next());
        log_full(core::debug, r2.next());
        log_full(core::debug, r2.next());
        log_full(core::debug, r2.next());
    }
    log_full(core::debug, r1.next());
    log_full(core::debug, r1.next());
}

#[test]
fn genstr() {
    let r: rand::rng = rand::mk_rng();
    log_full(core::debug, r.gen_str(10u));
    log_full(core::debug, r.gen_str(10u));
    log_full(core::debug, r.gen_str(10u));
    assert(str::char_len(r.gen_str(10u)) == 10u);
    assert(str::char_len(r.gen_str(16u)) == 16u);
}
<commit_msg>Register new snapshots, purge log_err and log_full in favour of log(...).<commit_after>import core::*;

// -*- rust -*-
use std;
import std::rand;
import str;

#[test]
fn test() {
    let r1: rand::rng = rand::mk_rng();
    log(debug, r1.next());
    log(debug, r1.next());
    {
        let r2 = rand::mk_rng();
        log(debug, r1.next());
        log(debug, r2.next());
        log(debug, r1.next());
        log(debug, r1.next());
        log(debug, r2.next());
        log(debug, r2.next());
        log(debug, r1.next());
        log(debug, r1.next());
        log(debug, r1.next());
        log(debug, r2.next());
        log(debug, r2.next());
        log(debug, r2.next());
    }
    log(debug, r1.next());
    log(debug, r1.next());
}

#[test]
fn genstr() {
    let r: rand::rng = rand::mk_rng();
    log(debug, r.gen_str(10u));
    log(debug, r.gen_str(10u));
    log(debug, r.gen_str(10u));
    assert(str::char_len(r.gen_str(10u)) == 10u);
    assert(str::char_len(r.gen_str(16u)) == 16u);
}
<|endoftext|>