use crate::proto::streaming_api;
use std::convert::TryFrom;
pub use crate::proto::streaming_api::GooseStatus;
#[derive(Debug, Clone)]
pub enum GooseReal {
Binary(i64, u32, i64),
ASCII(String),
PosInf(),
NegInf(),
NaN(),
NegZero(),
}
#[derive(Debug, Clone)]
pub struct GooseBitStr {
pub padding: u32,
pub bits: Vec<u8>,
}
#[derive(Debug)]
pub enum GooseData {
Array(Vec<GooseData>),
Struct(Vec<GooseData>),
Bool(bool),
BitStr(GooseBitStr),
Int(i64),
UInt(u64),
Double(f64),
Real(GooseReal),
Binary(Vec<u8>),
String(String),
TimeOfDay(String),
BCD(u64),
BoolArray(Vec<bool>),
ObjId(String),
MssString(String),
UTCTime(u64),
}
#[derive(Debug)]
pub struct GooseEvent {
pub go_id: String,
pub status: GooseStatus,
pub gocb_ref: String,
pub ttl: i64,
pub dat_set: String,
pub t: u64,
pub st_num: u32,
pub sq_num: u32,
pub test: bool,
pub conf_rev: u32,
pub nds_com: bool,
pub num_data: u32,
pub all_data: Vec<GooseData>,
}
impl GooseReal {
fn from_proto(r: streaming_api::GooseReal) -> Self {
match r.real.unwrap() {
streaming_api::goose_real::Real::Special(x) => {
match streaming_api::GooseSpecialReal::try_from(x).unwrap() {
streaming_api::GooseSpecialReal::PosInf => Self::PosInf(),
streaming_api::GooseSpecialReal::NegInf => Self::NegInf(),
streaming_api::GooseSpecialReal::NaN => Self::NaN(),
streaming_api::GooseSpecialReal::NegZero => Self::NegZero(),
}
}
streaming_api::goose_real::Real::Binary(streaming_api::GooseBinaryReal {
mantissa: n,
base: b,
exponent: e,
}) => Self::Binary(n, b, e),
streaming_api::goose_real::Real::Ascii(s) => Self::ASCII(s),
}
}
}
impl GooseBitStr {
fn from_proto(r: streaming_api::BitStr) -> Self {
GooseBitStr {
padding: r.padding,
bits: r.bit_str,
}
}
}
impl GooseData {
fn from_data(data: streaming_api::GooseData) -> Self {
let streaming_api::GooseData { data: inner } = data;
match inner {
None => panic!("Missing data"),
Some(streaming_api::goose_data::Data::Array(streaming_api::GooseDataArray { array: xs })) => {
Self::Array(Self::from_vec(xs))
}
Some(streaming_api::goose_data::Data::Struct(streaming_api::GooseDataStruct {
r#struct: xs,
})) => Self::Struct(Self::from_vec(xs)),
Some(streaming_api::goose_data::Data::Boolean(b)) => Self::Bool(b),
Some(streaming_api::goose_data::Data::BitStr(bs)) => {
Self::BitStr(GooseBitStr::from_proto(bs))
}
Some(streaming_api::goose_data::Data::Int(x)) => Self::Int(x),
Some(streaming_api::goose_data::Data::Uint(x)) => Self::UInt(x),
Some(streaming_api::goose_data::Data::Dbl(x)) => Self::Double(x),
Some(streaming_api::goose_data::Data::Real(x)) => Self::Real(GooseReal::from_proto(x)),
Some(streaming_api::goose_data::Data::Binary(x)) => Self::Binary(x),
Some(streaming_api::goose_data::Data::Str(x)) => Self::String(x),
Some(streaming_api::goose_data::Data::TimeOfDay(x)) => Self::TimeOfDay(x),
Some(streaming_api::goose_data::Data::Bcd(x)) => Self::BCD(x),
Some(streaming_api::goose_data::Data::BoolArray(streaming_api::BoolArray { bools: bs })) => {
Self::BoolArray(bs)
}
Some(streaming_api::goose_data::Data::ObjId(x)) => Self::ObjId(x),
Some(streaming_api::goose_data::Data::MssString(x)) => Self::MssString(x),
Some(streaming_api::goose_data::Data::UtcTime(x)) => Self::UTCTime(x),
}
}
fn from_vec(data: Vec<streaming_api::GooseData>) -> Vec<Self> {
data.into_iter().map(GooseData::from_data).collect()
}
}
impl GooseEvent {
pub fn new(pkt: streaming_api::GoosePacket) -> Self {
let status = pkt.status();
GooseEvent {
go_id: pkt.go_id,
status,
gocb_ref: pkt.gocb_ref,
ttl: pkt.ttl,
dat_set: pkt.dat_set,
t: pkt.t,
st_num: pkt.st_num,
sq_num: pkt.sq_num,
test: pkt.test,
conf_rev: pkt.conf_rev,
nds_com: pkt.nds_com,
num_data: pkt.num_data,
all_data: GooseData::from_vec(pkt.all_data),
}
}
}