pub fn run(
    entry: Entry,
    http_client: &mut http::Client,
    entry_index: usize,
    variables: &mut HashMap<String, Value>,
    log_verbose: &impl Fn(&str),
    log_error_message: &impl Fn(bool, &str),
    options: &RunnerOptions,
) -> Vec<EntryResult> {
    let http_request = match eval_request(
        entry.request.clone(),
        variables,
        options.context_dir.clone(),
    ) {
        Ok(r) => r,
        Err(error) => {
            return vec![EntryResult {
                request: None,
                response: None,
                captures: vec![],
                asserts: vec![],
                errors: vec![error],
                time_in_ms: 0,
            }];
        }
    };

    log_verbose("------------------------------------------------------------------------------");
    log_verbose(format!("executing entry {}", entry_index + 1).as_str());

    //
    // Experimental features
    // with cookie storage
    //
    use std::str::FromStr;
    if let Some(s) = cookie_storage_set(entry.request.clone()) {
        if let Ok(cookie) = http::Cookie::from_str(s.as_str()) {
            http_client.add_cookie(cookie);
        } else {
            log_error_message(
                true,
                format!("cookie string can not be parsed: '{}'", s).as_str(),
            );
        }
    }
    if cookie_storage_clear(entry.request.clone()) {
        http_client.clear_cookie_storage();
    }

    log_verbose("");
    log_verbose("Cookie store:");
    for cookie in http_client.get_cookie_storage() {
        log_verbose(cookie.to_string().as_str());
    }
    log_verbose("");
    log_request(log_verbose, &http_request);
    log_verbose(
        format!(
            "request can be run with the following curl command:\n* {}\n*",
            http_client.curl_command_line(&http_request)
        )
        .as_str(),
    );

    let calls = match http_client.execute_with_redirect(&http_request) {
        Ok(calls) => calls,
        Err(http_error) => {
            let runner_error = match http_error {
                HttpError::TooManyRedirect => RunnerError::TooManyRedirect,
                HttpError::CouldNotParseResponse => RunnerError::CouldNotParseResponse,
                HttpError::StatuslineIsMissing => RunnerError::HttpConnection {
                    message: "status line is missing".to_string(),
                    url: http_request.url.clone(),
                },
                HttpError::Libcurl { code, description } => RunnerError::HttpConnection {
                    message: format!("({}) {}", code, description),
                    url: http_request.url.clone(),
                },
            };
            return vec![EntryResult {
                request: None,
                response: None,
                captures: vec![],
                asserts: vec![],
                errors: vec![Error {
                    source_info: SourceInfo {
                        start: entry.request.url.source_info.start,
                        end: entry.request.url.source_info.end,
                    },
                    inner: runner_error,
                    assert: false,
                }],
                time_in_ms: 0,
            }];
        }
    };

    let mut entry_results = vec![];
    for (i, (http_request, http_response)) in calls.iter().enumerate() {
        let mut captures = vec![];
        let mut asserts = vec![];
        let mut errors = vec![];
        let time_in_ms = http_response.duration.as_millis();

        // Last call
        if i == calls.len() - 1 {
            captures = match entry.response.clone() {
                None => vec![],
                Some(response) => match eval_captures(response, http_response, variables) {
                    Ok(captures) => captures,
                    Err(e) => {
                        return vec![EntryResult {
                            request: Some(http_request.clone()),
                            response: Some(http_response.clone()),
                            captures: vec![],
                            asserts: vec![],
                            errors: vec![e],
                            time_in_ms,
                        }];
                    }
                },
            };
            // update variables now!
            for capture_result in captures.clone() {
                variables.insert(capture_result.name, capture_result.value);
            }
            asserts = if options.ignore_asserts {
                vec![]
            } else {
                match entry.response.clone() {
                    None => vec![],
                    Some(response) => eval_asserts(
                        response,
                        variables,
                        http_response.clone(),
                        options.context_dir.clone(),
                    ),
                }
            };
            errors = asserts
                .iter()
                .filter_map(|assert| assert.clone().error())
                .map(
                    |Error {
                         source_info, inner, ..
                     }| Error {
                        source_info,
                        inner,
                        assert: true,
                    },
                )
                .collect();

            if !captures.is_empty() {
                log_verbose("Captures");
                for capture in captures.clone() {
                    log_verbose(format!("{}: {}", capture.name, capture.value).as_str());
                }
            }
            log_verbose("");
        }

        let entry_result = EntryResult {
            request: Some(http_request.clone()),
            response: Some(http_response.clone()),
            captures,
            asserts,
            errors,
            time_in_ms,
        };
        entry_results.push(entry_result);
    }

    entry_results
}
/// Run an entry with the hurl http client
/// Return one or more EntryResults (if following redirect)
///
/// # Examples
///
/// ```
/// use hurl::http;
/// use hurl::runner;
///
/// // Create an http client
//// let client = http::client::Client::init(http::client::ClientOptions {
////        noproxy_hosts: vec![],
////        insecure: false,
////        redirect: http::client::Redirect::None,
////        http_proxy: None,
////        https_proxy: None,
////        all_proxy: None
////    });
/// ```
Run an entry with the hurl http client
Return one or more EntryResults (if following redirect)
Run an entry with the hurl http client Return one or more EntryResults ( if following redirect )
pub fn run(
    entry: Entry,
    http_client: &mut http::Client,
    entry_index: usize,
    variables: &mut HashMap<String, Value>,
    log_verbose: &impl Fn(&str),
    log_error_message: &impl Fn(bool, &str),
    options: &RunnerOptions,
) -> Vec<EntryResult> {
    let http_request = match eval_request(
        entry.request.clone(),
        variables,
        options.context_dir.clone(),
    ) {
        Ok(r) => r,
        Err(error) => {
            return vec![EntryResult {
                request: None,
                response: None,
                captures: vec![],
                asserts: vec![],
                errors: vec![error],
                time_in_ms: 0,
            }];
        }
    };
    log_verbose("------------------------------------------------------------------------------");
    log_verbose(format!("executing entry {}", entry_index + 1).as_str());
    //
    // Experimental features
    // with cookie storage
    //
    use std::str::FromStr;
    if let Some(s) = cookie_storage_set(entry.request.clone()) {
        if let Ok(cookie) = http::Cookie::from_str(s.as_str()) {
            http_client.add_cookie(cookie);
        } else {
            log_error_message(
                true,
                format!("cookie string can not be parsed: '{}'", s).as_str(),
            );
        }
    }
    if cookie_storage_clear(entry.request.clone()) {
        http_client.clear_cookie_storage();
    }
    log_verbose("");
    log_verbose("Cookie store:");
    for cookie in http_client.get_cookie_storage() {
        log_verbose(cookie.to_string().as_str());
    }
    log_verbose("");
    log_request(log_verbose, &http_request);
    log_verbose(
        format!(
            "request can be run with the following curl command:\n* {}\n*",
            http_client.curl_command_line(&http_request)
        )
        .as_str(),
    );
    let calls = match http_client.execute_with_redirect(&http_request) {
        Ok(calls) => calls,
        Err(http_error) => {
            let runner_error = match http_error {
                HttpError::TooManyRedirect => RunnerError::TooManyRedirect,
                HttpError::CouldNotParseResponse => RunnerError::CouldNotParseResponse,
                HttpError::StatuslineIsMissing => RunnerError::HttpConnection {
                    message: "status line is missing".to_string(),
                    url: http_request.url.clone(),
                },
                HttpError::Libcurl { code, description } => RunnerError::HttpConnection {
                    message: format!("({}) {}", code, description),
                    url: http_request.url.clone(),
                },
            };
            return vec![EntryResult {
                request: None,
                response: None,
                captures: vec![],
                asserts: vec![],
                errors: vec![Error {
                    source_info: SourceInfo {
                        start: entry.request.url.source_info.start,
                        end: entry.request.url.source_info.end,
                    },
                    inner: runner_error,
                    assert: false,
                }],
                time_in_ms: 0,
            }];
        }
    };
    let mut entry_results = vec![];
    for (i, (http_request, http_response)) in calls.iter().enumerate() {
        let mut captures = vec![];
        let mut asserts = vec![];
        let mut errors = vec![];
        let time_in_ms = http_response.duration.as_millis();
        // Last call
        if i == calls.len() - 1 {
            captures = match entry.response.clone() {
                None => vec![],
                Some(response) => match eval_captures(response, http_response, variables) {
                    Ok(captures) => captures,
                    Err(e) => {
                        return vec![EntryResult {
                            request: Some(http_request.clone()),
                            response: Some(http_response.clone()),
                            captures: vec![],
                            asserts: vec![],
                            errors: vec![e],
                            time_in_ms,
                        }];
                    }
                },
            };
            // update variables now!
            for capture_result in captures.clone() {
                variables.insert(capture_result.name, capture_result.value);
            }
            asserts = if options.ignore_asserts {
                vec![]
            } else {
                match entry.response.clone() {
                    None => vec![],
                    Some(response) => eval_asserts(
                        response,
                        variables,
                        http_response.clone(),
                        options.context_dir.clone(),
                    ),
                }
            };
            errors = asserts
                .iter()
                .filter_map(|assert| assert.clone().error())
                .map(
                    |Error {
                         source_info, inner, ..
                     }| Error {
                        source_info,
                        inner,
                        assert: true,
                    },
                )
                .collect();
            if !captures.is_empty() {
                log_verbose("Captures");
                for capture in captures.clone() {
                    log_verbose(format!("{}: {}", capture.name, capture.value).as_str());
                }
            }
            log_verbose("");
        }
        let entry_result = EntryResult {
            request: Some(http_request.clone()),
            response: Some(http_response.clone()),
            captures,
            asserts,
            errors,
            time_in_ms,
        };
        entry_results.push(entry_result);
    }
    entry_results
}
pub fn run ( entry : Entry , http_client : & mut http :: Client , entry_index : usize , variables : & mut HashMap < String , Value > , log_verbose : & impl Fn ( & str ) , log_error_message : & impl Fn ( bool , & str ) , options : & RunnerOptions , ) -> Vec < EntryResult > { let http_request = match eval_request ( entry . request . clone ( ) , variables , options . context_dir . clone ( ) , ) { Ok ( r ) => r , Err ( error ) => { return vec ! [ EntryResult { request None response None captures vec [ ] asserts vec [ ] errors vec [ error ] time_in_ms 0 } ] ; } } ; log_verbose ( " " ) ; log_verbose ( format ! ( " " entry_index 1 ) . as_str ( ) ) ; // // Experimental features // with cookie storage // use std :: str :: FromStr ; if let Some ( s ) = cookie_storage_set ( entry . request . clone ( ) ) { if let Ok ( cookie ) = http :: Cookie :: from_str ( s . as_str ( ) ) { http_client . add_cookie ( cookie ) ; } else { log_error_message ( true , format ! ( " " s ) . as_str ( ) , ) ; } } if cookie_storage_clear ( entry . request . clone ( ) ) { http_client . clear_cookie_storage ( ) ; } log_verbose ( " " ) ; log_verbose ( " " ) ; for cookie in http_client . get_cookie_storage ( ) { log_verbose ( cookie . to_string ( ) . as_str ( ) ) ; } log_verbose ( " " ) ; log_request ( log_verbose , & http_request ) ; log_verbose ( format ! ( " \n \n " http_client curl_command_line ( http_request ) ) . as_str ( ) , ) ; let calls = match http_client . execute_with_redirect ( & http_request ) { Ok ( calls ) => calls , Err ( http_error ) => { let runner_error = match http_error { HttpError :: TooManyRedirect => RunnerError :: TooManyRedirect , HttpError :: CouldNotParseResponse => RunnerError :: CouldNotParseResponse , HttpError :: StatuslineIsMissing => RunnerError :: HttpConnection { message : " " . to_string ( ) , url : http_request . url . clone ( ) , } , HttpError :: Libcurl { code , description } => RunnerError :: HttpConnection { message : format ! ( " " code description ) , url : http_request . url . clone ( ) , } , } ; return vec ! [ EntryResult { request None response None captures vec [ ] asserts vec [ ] errors vec [ Error { source_info SourceInfo { start entry request url source_info start end entry request url source_info end } inner runner_error assert false } ] time_in_ms 0 } ] ; } } ; let mut entry_results = vec ! [ ] ; for ( i , ( http_request , http_response ) ) in calls . iter ( ) . enumerate ( ) { let mut captures = vec ! [ ] ; let mut asserts = vec ! [ ] ; let mut errors = vec ! [ ] ; let time_in_ms = http_response . duration . as_millis ( ) ; // Last call if i == calls . len ( ) - 1 { captures = match entry . response . clone ( ) { None => vec ! [ ] , Some ( response ) => match eval_captures ( response , http_response , variables ) { Ok ( captures ) => captures , Err ( e ) => { return vec ! [ EntryResult { request Some ( http_request clone ( ) ) response Some ( http_response clone ( ) ) captures vec [ ] asserts vec [ ] errors vec [ e ] time_in_ms } ] ; } } , } ; // update variables now! for capture_result in captures . clone ( ) { variables . insert ( capture_result . name , capture_result . value ) ; } asserts = if options . ignore_asserts { vec ! [ ] } else { match entry . response . clone ( ) { None => vec ! [ ] , Some ( response ) => eval_asserts ( response , variables , http_response . clone ( ) , options . context_dir . clone ( ) , ) , } } ; errors = asserts . iter ( ) . filter_map ( | assert | assert . clone ( ) . error ( ) ) . map ( | Error { source_info , inner , .. } | Error { source_info , inner , assert : true , } , ) . collect ( ) ; if ! captures . is_empty ( ) { log_verbose ( " " ) ; for capture in captures . clone ( ) { log_verbose ( format ! ( " " capture name capture value ) . as_str ( ) ) ; } } log_verbose ( " " ) ; } let entry_result = EntryResult { request : Some ( http_request . clone ( ) ) , response : Some ( http_response . clone ( ) ) , captures , asserts , errors , time_in_ms , } ; entry_results . push ( entry_result ) ; } entry_results }
Run an entry with the hurl http client
Return one or more EntryResults (if following redirect)
Run an entry with the hurl http client Return one or more EntryResults ( if following redirect )
entry
Entry
http_client
&mut http::Client
entry_index
usize
variables
&mut HashMap<String, Value>
log_verbose
&impl Fn(&str)
log_error_message
&impl Fn(bool, &str)
options
&RunnerOptions
entry
Entry
http_client
&mut http::Client
entry_index
usize
variables
&mut HashMap<String, Value>
log_verbose
&impl Fn(&str)
log_error_message
&impl Fn(bool, &str)
options
&RunnerOptions
examples
```
use hurl::http;
use hurl::runner.

Create an http client
let client = http::client::Client::init(http::client::ClientOptions {
noproxy_hosts: vec![],
insecure: false,
redirect: http::client::Redirect::None,
http_proxy: None,
https_proxy: None,
all_proxy: None
});
```
` ` ` use hurl :: http ; use hurl :: runner . Create an http client let client = http :: client :: Client :: init ( http :: client :: ClientOptions { noproxy_hosts : vec! [] insecure : false redirect : http :: client :: Redirect :: None http_proxy : None https_proxy : None all_proxy : None } ) ; ` ` `