use core::qm;
use instruments::RcInstrument;
use instruments::assets::RcCurrency;
use risk::{RcReportGenerator, BoxReport};
use risk::marketdata::RcMarketData;
use data::fixings::RcFixingTable;
use pricers::RcPricerFactory;
#[derive(Debug)]
pub enum Handle {
Empty,
Instrument(RcInstrument),
Currency(RcCurrency),
MarketData(RcMarketData),
FixingTable(RcFixingTable),
PricerFactory(RcPricerFactory),
ReportGenerator(RcReportGenerator),
Reports(Vec<BoxReport>),
Err(qm::Error),
}
impl Handle {
pub fn from_empty(result: Result<(), qm::Error>) -> Handle {
match result {
Ok(()) => Handle::Empty,
Err(err) => Handle::Err(err)
}
}
pub fn from_instrument(result: Result<RcInstrument, qm::Error>) -> Handle {
match result {
Ok(instr) => Handle::Instrument(instr),
Err(err) => Handle::Err(err)
}
}
pub fn from_currency(result: Result<RcCurrency, qm::Error>) -> Handle {
match result {
Ok(ccy) => Handle::Currency(ccy),
Err(err) => Handle::Err(err)
}
}
pub fn from_fixing_table(result: Result<RcFixingTable, qm::Error>) -> Handle {
match result {
Ok(fix) => Handle::FixingTable(fix),
Err(err) => Handle::Err(err)
}
}
pub fn from_market_data(result: Result<RcMarketData, qm::Error>) -> Handle {
match result {
Ok(mkt) => Handle::MarketData(mkt),
Err(err) => Handle::Err(err)
}
}
pub fn from_pricer_factory(result: Result<RcPricerFactory, qm::Error>) -> Handle {
match result {
Ok(pf) => Handle::PricerFactory(pf),
Err(err) => Handle::Err(err)
}
}
pub fn from_report_generator(result: Result<RcReportGenerator, qm::Error>) -> Handle {
match result {
Ok(gen) => Handle::ReportGenerator(gen),
Err(err) => Handle::Err(err)
}
}
pub fn from_reports(result: Result<Vec<BoxReport>, qm::Error>) -> Handle {
match result {
Ok(reports) => Handle::Reports(reports),
Err(err) => Handle::Err(err)
}
}
pub fn from_error(error: qm::Error) -> Handle {
Handle::Err(error)
}
pub fn as_empty(&self) -> Result<(), qm::Error> {
match self {
&Handle::Empty => Ok(()),
&Handle::Err(ref err) => Err(err.clone()),
_ => Err(self.wrong_type("Empty"))
}
}
pub fn as_instrument(&self) -> Result<RcInstrument, qm::Error> {
match self {
&Handle::Instrument(ref instr) => Ok(instr.clone()),
&Handle::Err(ref err) => Err(err.clone()),
_ => Err(self.wrong_type("Instrument"))
}
}
pub fn as_currency(&self) -> Result<RcCurrency, qm::Error> {
match self {
&Handle::Currency(ref ccy) => Ok(ccy.clone()),
&Handle::Err(ref err) => Err(err.clone()),
_ => Err(self.wrong_type("Currency"))
}
}
pub fn as_market_data(&self) -> Result<RcMarketData, qm::Error> {
match self {
&Handle::MarketData(ref mkt) => Ok(mkt.clone()),
&Handle::Err(ref err) => Err(err.clone()),
_ => Err(self.wrong_type("MarketData"))
}
}
pub fn as_fixing_table(&self) -> Result<RcFixingTable, qm::Error> {
match self {
&Handle::FixingTable(ref fix) => Ok(fix.clone()),
&Handle::Err(ref err) => Err(err.clone()),
_ => Err(self.wrong_type("FixingTable"))
}
}
pub fn as_pricer_factory(&self) -> Result<RcPricerFactory, qm::Error> {
match self {
&Handle::PricerFactory(ref pf) => Ok(pf.clone()),
&Handle::Err(ref err) => Err(err.clone()),
_ => Err(self.wrong_type("PricerFactory"))
}
}
pub fn as_report_generator(&self) -> Result<RcReportGenerator, qm::Error> {
match self {
&Handle::ReportGenerator(ref gen) => Ok(gen.clone()),
&Handle::Err(ref err) => Err(err.clone()),
_ => Err(self.wrong_type("ReportGenerator"))
}
}
pub fn as_reports(self) -> Result<Vec<BoxReport>, qm::Error> {
match self {
Handle::Reports(reports) => Ok(reports),
Handle::Err(err) => Err(err),
_ => Err(self.wrong_type("Reports"))
}
}
pub fn as_error(&self) -> qm::Error {
match self {
&Handle::Err(ref err) => err.clone(),
_ => self.wrong_type("Error")
}
}
fn wrong_type(&self, requested: &str) -> qm::Error {
let supplied = match self {
&Handle::Empty => "Empty",
&Handle::Instrument(_) => "Instrument",
&Handle::Currency(_) => "Currency",
&Handle::MarketData(_) => "MarketData",
&Handle::FixingTable(_) => "FixingTable",
&Handle::PricerFactory(_) => "PricerFactory",
&Handle::ReportGenerator(_) => "ReportGenerator",
&Handle::Reports(_) => "Reports",
&Handle::Err(_) => "Error"
};
qm::Error::new(&format!("Wrong handle type: {} required but {} supplied", requested, supplied))
}
}
impl Clone for Handle {
fn clone(&self) -> Handle {
match self {
&Handle::Empty => Handle::Empty,
&Handle::Instrument(ref instr) => Handle::Instrument(instr.clone()),
&Handle::Currency(ref ccy) => Handle::Currency(ccy.clone()),
&Handle::MarketData(ref mkt) => Handle::MarketData(mkt.clone()),
&Handle::FixingTable(ref fix) => Handle::FixingTable(fix.clone()),
&Handle::PricerFactory(ref pf) => Handle::PricerFactory(pf.clone()),
&Handle::ReportGenerator(ref gen) => Handle::ReportGenerator(gen.clone()),
&Handle::Reports(_) => Handle::Err(qm::Error::new("Reports cannot be cloned")),
&Handle::Err(ref err) => Handle::Err(err.clone())
}
}
}
pub mod extern_handle {
use super::*;
use instruments::RcInstrument;
use instruments::assets::RcCurrency;
use risk::RcReportGenerator;
use risk::marketdata::RcMarketData;
use data::fixings::RcFixingTable;
use pricers::RcPricerFactory;
use facade::write_results;
use std::error::Error;
use std::io::Cursor;
pub fn from_handle(result: Result<Handle, qm::Error>) -> u64 {
let boxed = Box::new( match result {
Ok(handle) => handle,
Err(err) => Handle::from_error(err) });
Box::into_raw(boxed) as u64
}
pub fn clone_handle(handle: u64) -> u64 {
println!("clone_handle: {}", handle);
let cloned = Box::new(handle_from_ext(handle).clone());
Box::into_raw(cloned) as u64
}
pub fn as_instrument(handle: u64) -> Result<RcInstrument, qm::Error> {
handle_from_ext(handle).as_instrument()
}
pub fn as_currency(handle: u64) -> Result<RcCurrency, qm::Error> {
handle_from_ext(handle).as_currency()
}
pub fn as_market_data(handle: u64) -> Result<RcMarketData, qm::Error> {
handle_from_ext(handle).as_market_data()
}
pub fn as_fixing_table(handle: u64) -> Result<RcFixingTable, qm::Error> {
handle_from_ext(handle).as_fixing_table()
}
pub fn as_pricer_factory(handle: u64) -> Result<RcPricerFactory, qm::Error> {
handle_from_ext(handle).as_pricer_factory()
}
pub fn as_report_generator(handle: u64) -> Result<RcReportGenerator, qm::Error> {
handle_from_ext(handle).as_report_generator()
}
pub fn as_reports(handle_which_is_freed: u64) -> Result<Vec<BoxReport>, qm::Error> {
let handle = unsafe { Box::from_raw(handle_which_is_freed as *mut Handle) };
handle.as_reports()
}
pub fn reports_as_string(handle: u64) -> String {
let handle_ptr = handle as *mut Handle;
unsafe {
match *handle_ptr {
Handle::Reports(ref reports) => {
let mut buffer = Vec::new();
write_results(&reports, true, &mut Cursor::new(&mut buffer)).unwrap();
String::from_utf8(buffer).unwrap()
},
Handle::Err(ref err) => err.description().to_string(),
_ => "reports_as_string: not a report handle".to_string()
}
}
}
pub fn as_error(handle: u64) -> qm::Error {
handle_from_ext(handle).as_error()
}
pub fn is_error(handle: u64) -> bool {
if let &Handle::Err(_) = handle_from_ext(handle) { true } else { false }
}
pub fn free_handle(handle: u64) {
unsafe { Box::from_raw(handle as *mut Handle) };
}
fn handle_from_ext(handle: u64) -> &'static Handle {
let handle_ptr = handle as *mut Handle;
unsafe { &*handle_ptr }
}
}