use std::cell::RefCell;
use std::sync::{Arc, Mutex};
use std::io::{Error, ErrorKind};
use mock::{MockRequest, MockResponse};
pub struct ResponseProvider {
response_index: usize,
provided_responses: Vec<(Box<MockResponse + 'static>, usize, usize)>,
request_index: usize,
additional_requests: Vec<Box<MockRequest>>
}
impl ResponseProvider {
pub fn reset() {
let handler = PROVIDER_INSTANCE.clone();
match handler.lock() {
Ok(handler) => {
let mut provider = handler.borrow_mut();
provider.response_index = 0;
provider.request_index = 0;
},
_ => unreachable!()
};
}
pub fn provide(resources: Vec<Box<MockResponse + 'static>>) {
let handler = PROVIDER_INSTANCE.clone();
match handler.lock() {
Ok(handler) => {
let mut provider = handler.borrow_mut();
for resource in resources {
let index = provider.response_index;
provider.provided_responses.push((resource, index, 0));
provider.response_index += 1;
}
},
_ => unreachable!()
};
}
#[cfg_attr(feature = "clippy", allow(needless_return))]
pub fn provided_responses() -> Vec<(Box<MockResponse + 'static>, usize, usize)> {
let handler = PROVIDER_INSTANCE.clone();
return match handler.lock() {
Ok(handler) => {
let mut provider = handler.borrow_mut();
return provider.provided_responses.drain(0..).collect();
},
_ => Vec::new()
};
}
#[cfg_attr(feature = "clippy", allow(needless_return))]
pub fn additional_requests() -> Vec<Box<MockRequest + 'static>> {
let handler = PROVIDER_INSTANCE.clone();
return match handler.lock() {
Ok(handler) => {
let mut provider = handler.borrow_mut();
return provider.additional_requests.drain(0..).collect();
},
_ => Vec::new()
};
}
#[cfg_attr(feature = "clippy", allow(needless_return))]
pub fn request(
request: Box<MockRequest>
) -> Result<Result<Vec<u8>, Error>, Error> {
let handler = PROVIDER_INSTANCE.clone();
return match handler.lock() {
Ok(handler) => {
let mut provider = handler.borrow_mut();
let index = provider.request_index;
provider.request_index += 1;
for &mut(
ref mut response,
_,
ref mut request_index
) in &mut provider.provided_responses {
if response.matches(&request) {
*request_index = index;
return Ok(response.respond(request));
}
}
provider.additional_requests.push(request);
Err(Error::new(
ErrorKind::ConnectionRefused,
"Noir: No response provided in test."
))
},
_ => Err(Error::new(
ErrorKind::ConnectionReset,
"Noir: Handler lock failed."
))
};
}
}
lazy_static! {
static ref PROVIDER_INSTANCE: Arc<Mutex<RefCell<ResponseProvider>>> = {
Arc::new(Mutex::new(RefCell::new(ResponseProvider {
response_index: 0,
provided_responses: Vec::new(),
request_index: 0,
additional_requests: Vec::new()
})))
};
}