use crate::error::{CaError, CaResult};
use crate::server::record::{FieldDesc, ProcessOutcome, Record};
use crate::types::{DbFieldType, EpicsValue};
pub struct SubRecord {
pub val: f64,
pub snam: String,
pub inpa: String,
pub inpb: String,
pub inpc: String,
pub inpd: String,
pub inpe: String,
pub inpf: String,
pub inpg: String,
pub inph: String,
pub inpi: String,
pub inpj: String,
pub inpk: String,
pub inpl: String,
pub a: f64,
pub b: f64,
pub c: f64,
pub d: f64,
pub e: f64,
pub f: f64,
pub g: f64,
pub h: f64,
pub i: f64,
pub j: f64,
pub k: f64,
pub l: f64,
}
impl Default for SubRecord {
fn default() -> Self {
Self {
val: 0.0,
snam: String::new(),
inpa: String::new(),
inpb: String::new(),
inpc: String::new(),
inpd: String::new(),
inpe: String::new(),
inpf: String::new(),
inpg: String::new(),
inph: String::new(),
inpi: String::new(),
inpj: String::new(),
inpk: String::new(),
inpl: String::new(),
a: 0.0,
b: 0.0,
c: 0.0,
d: 0.0,
e: 0.0,
f: 0.0,
g: 0.0,
h: 0.0,
i: 0.0,
j: 0.0,
k: 0.0,
l: 0.0,
}
}
}
static SUB_FIELDS: &[FieldDesc] = &[
FieldDesc {
name: "VAL",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "SNAM",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPA",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPB",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPC",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPD",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPE",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPF",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPG",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPH",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPI",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPJ",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPK",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "INPL",
dbf_type: DbFieldType::String,
read_only: false,
},
FieldDesc {
name: "A",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "B",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "C",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "D",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "E",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "F",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "G",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "H",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "I",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "J",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "K",
dbf_type: DbFieldType::Double,
read_only: false,
},
FieldDesc {
name: "L",
dbf_type: DbFieldType::Double,
read_only: false,
},
];
impl Record for SubRecord {
fn record_type(&self) -> &'static str {
"sub"
}
fn process(&mut self) -> CaResult<ProcessOutcome> {
Ok(ProcessOutcome::complete())
}
fn get_field(&self, name: &str) -> Option<EpicsValue> {
match name {
"VAL" => Some(EpicsValue::Double(self.val)),
"SNAM" => Some(EpicsValue::String(self.snam.clone())),
"INPA" => Some(EpicsValue::String(self.inpa.clone())),
"INPB" => Some(EpicsValue::String(self.inpb.clone())),
"INPC" => Some(EpicsValue::String(self.inpc.clone())),
"INPD" => Some(EpicsValue::String(self.inpd.clone())),
"INPE" => Some(EpicsValue::String(self.inpe.clone())),
"INPF" => Some(EpicsValue::String(self.inpf.clone())),
"INPG" => Some(EpicsValue::String(self.inpg.clone())),
"INPH" => Some(EpicsValue::String(self.inph.clone())),
"INPI" => Some(EpicsValue::String(self.inpi.clone())),
"INPJ" => Some(EpicsValue::String(self.inpj.clone())),
"INPK" => Some(EpicsValue::String(self.inpk.clone())),
"INPL" => Some(EpicsValue::String(self.inpl.clone())),
"A" => Some(EpicsValue::Double(self.a)),
"B" => Some(EpicsValue::Double(self.b)),
"C" => Some(EpicsValue::Double(self.c)),
"D" => Some(EpicsValue::Double(self.d)),
"E" => Some(EpicsValue::Double(self.e)),
"F" => Some(EpicsValue::Double(self.f)),
"G" => Some(EpicsValue::Double(self.g)),
"H" => Some(EpicsValue::Double(self.h)),
"I" => Some(EpicsValue::Double(self.i)),
"J" => Some(EpicsValue::Double(self.j)),
"K" => Some(EpicsValue::Double(self.k)),
"L" => Some(EpicsValue::Double(self.l)),
_ => None,
}
}
fn put_field(&mut self, name: &str, value: EpicsValue) -> CaResult<()> {
match name {
"VAL" => match value {
EpicsValue::Double(v) => {
self.val = v;
Ok(())
}
_ => Err(CaError::TypeMismatch("VAL".into())),
},
"SNAM" => match value {
EpicsValue::String(s) => {
self.snam = s;
Ok(())
}
_ => Err(CaError::TypeMismatch("SNAM".into())),
},
"INPA" | "INPB" | "INPC" | "INPD" | "INPE" | "INPF" | "INPG" | "INPH" | "INPI"
| "INPJ" | "INPK" | "INPL" => match value {
EpicsValue::String(s) => {
match name {
"INPA" => self.inpa = s,
"INPB" => self.inpb = s,
"INPC" => self.inpc = s,
"INPD" => self.inpd = s,
"INPE" => self.inpe = s,
"INPF" => self.inpf = s,
"INPG" => self.inpg = s,
"INPH" => self.inph = s,
"INPI" => self.inpi = s,
"INPJ" => self.inpj = s,
"INPK" => self.inpk = s,
"INPL" => self.inpl = s,
_ => unreachable!(),
}
Ok(())
}
_ => Err(CaError::TypeMismatch(name.into())),
},
"A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" => {
let v = value
.to_f64()
.ok_or_else(|| CaError::TypeMismatch(name.into()))?;
match name {
"A" => self.a = v,
"B" => self.b = v,
"C" => self.c = v,
"D" => self.d = v,
"E" => self.e = v,
"F" => self.f = v,
"G" => self.g = v,
"H" => self.h = v,
"I" => self.i = v,
"J" => self.j = v,
"K" => self.k = v,
"L" => self.l = v,
_ => unreachable!(),
}
Ok(())
}
_ => Err(CaError::FieldNotFound(name.to_string())),
}
}
fn field_list(&self) -> &'static [FieldDesc] {
SUB_FIELDS
}
fn multi_input_links(&self) -> &[(&'static str, &'static str)] {
&[
("INPA", "A"),
("INPB", "B"),
("INPC", "C"),
("INPD", "D"),
("INPE", "E"),
("INPF", "F"),
("INPG", "G"),
("INPH", "H"),
("INPI", "I"),
("INPJ", "J"),
("INPK", "K"),
("INPL", "L"),
]
}
}