use super::connection::Connection;
use super::error::Error;
use super::params::*;
use super::{spec, util, Field, FixedField, Message};
use std::str;
pub struct Client {
connection: Connection,
}
impl Client {
pub fn new(host: &str) -> Result<Self, Error> {
Ok(Client {
connection: Connection::new(host)?,
})
}
pub fn disconnect(&self) -> Result<(), Error> {
self.connection.disconnect()
}
pub fn login(&mut self, params: &ParamSet) -> Result<SipResponse, Error> {
let user = match params.sip_user() {
Some(u) => u,
_ => return Err(Error::MissingParamsError),
};
let pass = match params.sip_pass() {
Some(u) => u,
_ => return Err(Error::MissingParamsError),
};
let mut req = Message::new(
&spec::M_LOGIN,
vec![
FixedField::new(&spec::FF_UID_ALGO, "0").unwrap(),
FixedField::new(&spec::FF_PWD_ALGO, "0").unwrap(),
],
vec![
Field::new(spec::F_LOGIN_UID.code, user),
Field::new(spec::F_LOGIN_PWD.code, pass),
],
);
req.maybe_add_field(spec::F_LOCATION_CODE.code, params.location());
let resp = self.connection.sendrecv(&req)?;
if resp.spec().code == spec::M_LOGIN_RESP.code
&& resp.fixed_fields().len() == 1
&& resp.fixed_fields()[0].value() == "1"
{
Ok(SipResponse::new(resp, true))
} else {
Ok(SipResponse::new(resp, false))
}
}
pub fn sc_status(&mut self) -> Result<SipResponse, Error> {
let req = Message::new(
&spec::M_SC_STATUS,
vec![
FixedField::new(&spec::FF_STATUS_CODE, "0").unwrap(),
FixedField::new(&spec::FF_MAX_PRINT_WIDTH, "999").unwrap(),
FixedField::new(&spec::FF_PROTOCOL_VERSION, spec::SIP_PROTOCOL_VERSION).unwrap(),
],
vec![],
);
let resp = self.connection.sendrecv(&req)?;
if !resp.fixed_fields().is_empty() && resp.fixed_fields()[0].value() == "Y" {
Ok(SipResponse::new(resp, true))
} else {
Ok(SipResponse::new(resp, false))
}
}
pub fn patron_status(&mut self, params: &ParamSet) -> Result<SipResponse, Error> {
let patron_id = match params.patron_id() {
Some(p) => p,
_ => return Err(Error::MissingParamsError),
};
let mut req = Message::new(
&spec::M_PATRON_STATUS,
vec![
FixedField::new(&spec::FF_LANGUAGE, "000").unwrap(),
FixedField::new(&spec::FF_DATE, &util::sip_date_now()).unwrap(),
],
vec![Field::new(spec::F_PATRON_ID.code, patron_id)],
);
req.maybe_add_field(spec::F_INSTITUTION_ID.code, params.institution());
req.maybe_add_field(spec::F_PATRON_PWD.code, params.patron_pwd());
req.maybe_add_field(spec::F_TERMINAL_PWD.code, params.terminal_pwd());
let resp = self.connection.sendrecv(&req)?;
if let Some(bl_val) = resp.get_field_value(spec::F_VALID_PATRON.code) {
if bl_val == "Y" {
return Ok(SipResponse::new(resp, true));
}
}
Ok(SipResponse::new(resp, false))
}
pub fn patron_info(&mut self, params: &ParamSet) -> Result<SipResponse, Error> {
let patron_id = match params.patron_id() {
Some(p) => p,
None => return Err(Error::MissingParamsError),
};
let mut summary: [char; 10] = [' '; 10];
if let Some(idx) = params.summary() {
if idx < 10 {
summary[idx] = 'Y';
}
}
let sum_str: String = summary.iter().collect::<String>();
let mut req = Message::new(
&spec::M_PATRON_INFO,
vec![
FixedField::new(&spec::FF_LANGUAGE, "000").unwrap(),
FixedField::new(&spec::FF_DATE, &util::sip_date_now()).unwrap(),
FixedField::new(&spec::FF_SUMMARY, &sum_str).unwrap(),
],
vec![Field::new(spec::F_PATRON_ID.code, patron_id)],
);
req.maybe_add_field(spec::F_INSTITUTION_ID.code, params.institution());
req.maybe_add_field(spec::F_PATRON_PWD.code, params.patron_pwd());
req.maybe_add_field(spec::F_TERMINAL_PWD.code, params.terminal_pwd());
if let Some(v) = params.start_item() {
req.add_field(spec::F_START_ITEM.code, &v.to_string());
}
if let Some(v) = params.end_item() {
req.add_field(spec::F_END_ITEM.code, &v.to_string());
}
let resp = self.connection.sendrecv(&req)?;
if let Some(bl_val) = resp.get_field_value(spec::F_VALID_PATRON.code) {
if bl_val == "Y" {
return Ok(SipResponse::new(resp, true));
}
}
Ok(SipResponse::new(resp, false))
}
pub fn item_info(&mut self, params: &ParamSet) -> Result<SipResponse, Error> {
let item_id = match params.item_id() {
Some(id) => id,
None => return Err(Error::MissingParamsError),
};
let mut req = Message::new(
&spec::M_ITEM_INFO,
vec![FixedField::new(&spec::FF_DATE, &util::sip_date_now()).unwrap()],
vec![Field::new(spec::F_ITEM_IDENT.code, item_id)],
);
req.maybe_add_field(spec::F_INSTITUTION_ID.code, params.institution());
req.maybe_add_field(spec::F_TERMINAL_PWD.code, params.terminal_pwd());
let resp = self.connection.sendrecv(&req)?;
if let Some(title_val) = resp.get_field_value(spec::F_TITLE_IDENT.code) {
if !title_val.is_empty() {
return Ok(SipResponse::new(resp, true));
}
}
Ok(SipResponse::new(resp, false))
}
pub fn checkout(&mut self, params: &ParamSet) -> Result<SipResponse, Error> {
let item_id = params.item_id().ok_or(Error::MissingParamsError)?;
let patron_id = params.patron_id().ok_or(Error::MissingParamsError)?;
let mut req = Message::from_values(
spec::M_CHECKOUT.code,
&[
"N", "N", &util::sip_date_now(), &util::sip_date_now(), ],
&[
(spec::F_ITEM_IDENT.code, item_id),
(spec::F_PATRON_IDENT.code, patron_id),
],
)?;
req.maybe_add_field(spec::F_INSTITUTION_ID.code, params.institution());
req.maybe_add_field(spec::F_TERMINAL_PWD.code, params.terminal_pwd());
req.maybe_add_field(spec::F_PATRON_PWD.code, params.patron_pwd());
let resp = self.connection.sendrecv(&req)?;
if let Some(status) = resp.fixed_fields().first() {
if status.value() == "1" {
return Ok(SipResponse::new(resp, true));
}
}
Ok(SipResponse::new(resp, false))
}
pub fn checkin(&mut self, params: &ParamSet) -> Result<SipResponse, Error> {
let item_id = params.item_id().ok_or(Error::MissingParamsError)?;
let mut req = Message::from_values(
spec::M_CHECKIN.code,
&[
"N", &util::sip_date_now(), &util::sip_date_now(), ],
&[(spec::F_ITEM_IDENT.code, item_id)],
)?;
req.maybe_add_field(spec::F_INSTITUTION_ID.code, params.institution());
req.maybe_add_field(spec::F_TERMINAL_PWD.code, params.terminal_pwd());
let resp = self.connection.sendrecv(&req)?;
if let Some(status) = resp.fixed_fields().first() {
if status.value() == "1" {
return Ok(SipResponse::new(resp, true));
}
}
Ok(SipResponse::new(resp, false))
}
pub fn fee_paid(&mut self, params: &ParamSet) -> Result<SipResponse, Error> {
let patron_id = params.patron_id().ok_or(Error::MissingParamsError)?;
let pay_amount = params.pay_amount().ok_or(Error::MissingParamsError)?;
let pay_amount = pay_amount.to_string();
let fee_type = params.fee_type().unwrap_or(spec::FeeType::OtherUnknown);
let pay_type = params.pay_type().unwrap_or(spec::PayType::Cash);
let mut req = Message::from_values(
spec::M_FEE_PAID.code,
&[
&util::sip_date_now(), fee_type.into(),
pay_type.into(),
"USD", ],
&[
(spec::F_PATRON_ID.code, patron_id),
(spec::F_FEE_AMOUNT.code, &pay_amount),
],
)?;
req.maybe_add_field(spec::F_INSTITUTION_ID.code, params.institution());
req.maybe_add_field(spec::F_TERMINAL_PWD.code, params.terminal_pwd());
req.maybe_add_field(spec::F_TRANSACTION_ID.code, params.transaction_id());
req.maybe_add_field(spec::F_FEE_IDENTIFIER.code, params.fee_id());
let resp = self.connection.sendrecv(&req)?;
if let Some(status) = resp.fixed_fields().first() {
if status.value() == "1" {
return Ok(SipResponse::new(resp, true));
}
}
Ok(SipResponse::new(resp, false))
}
}
pub struct SipResponse {
msg: Message,
ok: bool,
}
impl SipResponse {
pub fn new(msg: Message, ok: bool) -> Self {
SipResponse { msg, ok }
}
pub fn ok(&self) -> bool {
self.ok
}
pub fn msg(&self) -> &Message {
&self.msg
}
pub fn msg_mut(&mut self) -> &mut Message {
&mut self.msg
}
pub fn value(&self, code: &str) -> Option<&str> {
self.msg().get_field_value(code)
}
}