pub fn pp_fields_for(record_type: &str) -> &'static [&'static str] {
const MBB_PP: &[&str] = &[
"VAL", "ZRVL", "ONVL", "TWVL", "THVL", "FRVL", "FVVL", "SXVL", "SVVL", "EIVL", "NIVL",
"TEVL", "ELVL", "TVVL", "TTVL", "FTVL", "FFVL", "ZRST", "ONST", "TWST", "THST", "FRST",
"FVST", "SXST", "SVST", "EIST", "NIST", "TEST", "ELST", "TVST", "TTST", "FTST", "FFST",
"ZRSV", "ONSV", "TWSV", "THSV", "FRSV", "FVSV", "SXSV", "SVSV", "EISV", "NISV", "TESV",
"ELSV", "TVSV", "TTSV", "FTSV", "FFSV", "UNSV", "COSV", "RVAL",
];
match record_type {
"ai" => &[
"VAL", "LINR", "EGUF", "EGUL", "AOFF", "ASLO", "HIHI", "LOLO", "HIGH", "LOW", "HHSV",
"LLSV", "HSV", "LSV", "ESLO", "EOFF", "ROFF", "RVAL",
],
"ao" => &[
"VAL", "LINR", "EGUF", "EGUL", "ROFF", "EOFF", "ESLO", "DRVH", "DRVL", "AOFF", "ASLO",
"HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV", "RVAL",
],
"bi" => &["VAL", "ZSV", "OSV", "COSV", "ZNAM", "ONAM", "RVAL"],
"bo" => &["VAL", "ZNAM", "ONAM", "RVAL", "ZSV", "OSV", "COSV"],
"busy" => &["VAL", "ZNAM", "ONAM", "RVAL", "ZSV", "OSV", "COSV"],
"calc" => &[
"CALC", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV", "A", "B", "C",
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U",
],
"calcout" => &[
"CALC", "OCAL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV", "A", "B",
"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
"T", "U",
],
"compress" => &["VAL"],
"dfanout" => &[
"VAL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV",
],
"event" => &[],
"fanout" => &["VAL"],
"histogram" => &[],
"int64in" => &[
"VAL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV",
],
"int64out" => &[
"VAL", "DRVH", "DRVL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV",
],
"longin" => &[
"VAL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV",
],
"longout" => &[
"VAL", "DRVH", "DRVL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV",
],
"lsi" => &["VAL"],
"lso" => &["VAL"],
"mbbi" => MBB_PP,
"mbbo" => MBB_PP,
"mbbiDirect" => &[
"VAL", "RVAL", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB",
"BC", "BD", "BE", "BF", "B10", "B11", "B12", "B13", "B14", "B15", "B16", "B17", "B18",
"B19", "B1A", "B1B", "B1C", "B1D", "B1E", "B1F",
],
"mbboDirect" => &[
"VAL", "OMSL", "RVAL", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9",
"BA", "BB", "BC", "BD", "BE", "BF", "B10", "B11", "B12", "B13", "B14", "B15", "B16",
"B17", "B18", "B19", "B1A", "B1B", "B1C", "B1D", "B1E", "B1F",
],
"motor" => &[
"OFF", "DIR", "SREV", "UREV", "MRES", "ERES", "UEIP", "URIP", "HLM", "LLM", "DHLM",
"DLLM", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV", "HLSV", "SPMG",
"STOP", "HOMF", "HOMR", "JOGF", "JOGR", "TWF", "TWR", "VAL", "DVAL", "RVAL", "RLV",
"CNEN", "STUP", "SYNC", "PCOF", "ICOF", "DCOF", "JVEL",
],
"permissive" => &["VAL", "WFLG", "LABL"],
"printf" => &["VAL", "FMT"],
"sel" => &[
"HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV", "A", "B", "C", "D", "E",
"F", "G", "H", "I", "J", "K", "L",
],
"seq" => &["VAL"],
"state" => &["VAL"],
"stringin" => &["VAL", "SVAL"],
"stringout" => &["VAL"],
"sub" => &[
"VAL", "HIHI", "LOLO", "HIGH", "LOW", "BRSV", "HHSV", "LLSV", "HSV", "LSV", "A", "B",
"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
"T", "U",
],
"aSub" => &["BRSV"],
"waveform" => &["VAL", "RARM"],
"aai" => &["VAL"],
"aao" => &["VAL"],
"subArray" => &["VAL", "NELM", "INDX"],
"scalcout" => &[
"CALC", "OCAL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV", "HSV", "LSV", "A", "B",
"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "AA", "BB", "CC", "DD", "EE", "FF",
"GG", "HH", "II", "JJ", "KK", "LL",
],
"acalcout" => &[
"AVAL", "NUSE", "PAVL", "CALC", "OCAL", "HIHI", "LOLO", "HIGH", "LOW", "HHSV", "LLSV",
"HSV", "LSV", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "AA", "BB",
"CC", "DD", "EE", "FF", "GG", "HH", "II", "JJ", "KK", "LL", "OAV", "POAV",
],
"swait" => &["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"],
"transform" => &[
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
],
"sseq" => &["VAL"],
"scaler" => &["CNT", "CONT"],
"table" => &[
"LX", "LZ", "SX", "SY", "SZ", "RX", "RY", "RZ", "YANG", "AX", "AY", "AZ", "X", "Y",
"Z", "UHAX", "UHAY", "UHAZ", "UHX", "UHY", "UHZ", "ULAX", "ULAY", "ULAZ", "ULX", "ULY",
"ULZ", "UHAXR", "UHAYR", "UHAZR", "UHXR", "UHYR", "UHZR", "ULAXR", "ULAYR", "ULAZR",
"ULXR", "ULYR", "ULZR", "INIT", "ZERO", "SYNC", "READ", "GEOM", "AUNIT",
],
"epid" => &["VAL"],
"timestamp" => &["VAL", "RVAL"],
"throttle" => &["VAL"],
"asyn" => &[
"AOUT", "BOUT", "I32OUT", "UI32OUT", "F64OUT", "UCMD", "ACMD",
],
other => {
warn_unknown_record_type_once(other);
&[]
}
}
}
fn warn_unknown_record_type_once(record_type: &str) {
use std::collections::HashSet;
use std::sync::{Mutex, OnceLock};
static WARNED: OnceLock<Mutex<HashSet<String>>> = OnceLock::new();
let warned = WARNED.get_or_init(|| Mutex::new(HashSet::new()));
let is_new = warned
.lock()
.map(|mut set| set.insert(record_type.to_string()))
.unwrap_or(true);
if is_new {
tracing::warn!(
record_type,
"record type has no pp_fields_for entry; its field puts will never \
auto-process (PROC-only). Add its pp(TRUE) set to pp_fields_for."
);
}
}
#[cfg(test)]
mod tests {
use super::pp_fields_for;
#[test]
fn unmodeled_type_returns_empty_not_processing() {
assert!(
pp_fields_for("__definitely_not_a_record_type__").is_empty(),
"an unmodeled record type must return &[] (fail-safe, PROC-only)"
);
}
#[test]
fn modeled_type_with_pp_is_non_empty() {
assert!(
pp_fields_for("ai").contains(&"VAL"),
"ai declares VAL pp(TRUE); the modeled set must survive the flip"
);
assert!(
pp_fields_for("asyn").contains(&"AOUT"),
"asyn declares AOUT pp(TRUE); a put to AOUT must still process"
);
}
#[test]
fn modeled_empty_type_returns_empty() {
assert!(pp_fields_for("event").is_empty());
assert!(pp_fields_for("histogram").is_empty());
}
}