Crate epics_gen

Crate epics_gen 

Source
Expand description

§epics-gen

epics-gen is a set of helper macros that helps create parsers for serializing xlsx spreadsheets into data structures and deserializing them as EPICS PVs.

§Including epics-gen in Your Project

Import epics_gen and epics_gen_macros into your project by adding the following lines to your Cargo.toml. epics_gen_macros contains the macros needed to derive all the traits in epics-gen.

[dependencies]
epics_gen = "0.1"
epics_gen_macros = "0.1"

§Deserialization

Note that an external library calamine is used to read and store xlsx files and data. The used structures and functions from calamine are reexported in this crate convenience. See Type Aliases for more information.

The following code is a xlsx deserializing example:

use epics_gen::FromXlsxData;

let mut workbook: epics_gen::XlsxWorkbook = epics_gen::open_workbook("tests/test_parser1.xlsx")
    .expect("xlsx file for this test is missing!");

let parser = epics_gen::ParserBuilder::new(&mut workbook)
    .add_sheet("Sheet1")
    .expect("Sheet1 exists")
    .add_table("test_table_1")
    .expect("test_table_1 exists")
    .build();


#[derive(epics_gen::FromXlsxRow, Debug, PartialEq)]
struct TargetStruct {
   row_id: String,
   float1: f64,
   float2: f64,
}

let parsed: Vec<TargetStruct> = parser.parse().expect("Table is parsable");

Note that the struct members must implement traits that enable conversion from Xlsx types to target type. See FromXlsxData trait for more details (and the macros that automatically implement it).

and this an example of serializing structures to PVs:

use epics_gen::AsRecord;

#[derive(AsRecord)]
#[record(rec_name = "$(P)Voltage", rec_type = "ao")]
struct TestStruct {
    #[record(field = "DESC")]
    desc: &'static str,
    #[record(field = "EGU")]
    egu: &'static str,
    #[record(field = "VAL")]
    val: f64,
}

let test_struct = TestStruct {
    desc: "Output Voltage",
    egu: "V",
    val: 0.5,
};

assert_eq!(
    test_struct.as_record(),
    r#"record(ao, "$(P)Voltage") {
  field(DESC, "Output Voltage")
  field(EGU, "V")
  field(VAL, "0.5")
}
"#);

see AsRecord for more details.

§Serialization

To serialize struct the AsRecord macro is used. It comes with attributes to help the user define EPICS PVs for printing.

§Attributes

To use the AsRecord macro, these attributes need to be defined:

  • record name: #[record(rec_name = "<record_name>")] (e.g.: “$(P)Voltage”)
  • record type: #[record(rec_type = "<record_type>")] (e.g.: “ao”)
  • record field: #[record(field = "<field>")] (e.g.: “DESC”)

Optional attributes:

  • subst: #[record(subst = "<pattern>")]; substitutes a pattern in other fields. Similar to EPICS macro definitions.
  • fmt: #[record(fmt = "<user_defined_string>"]; overrides other attributes and lets the user define a custom output. (e.g.: #[record(fmt = r#"record(ao, "$(P):Voltage"){field(VAL, "{{}}")"#])
  • repr: #[record(repr = <type>)]; convert to type before printing the value; (e.g.: #[record(repr = u32)])

§Usage

The mandatory attributes name and type can be either set on the whole structure (global) or on a per field basis (local), which allows defining more records per struct.

Global record definition example:

#[derive(AsRecord)]
#[record(rec_name = "$(P)Voltage", rec_type = "ao")]
struct TestStruct {
#[record(field = "DESC")]
desc: &'static str,
#[record(field = "EGU")]
egu: &'static str,
#[record(field = "VAL")]
val: f64,
}

local record definition example:

#[derive(AsRecord)]
struct TestStruct {
    #[record(rec_name = "$(P)Voltage", rec_type = "ao")]
    #[record(field = "VAL")]
    voltage: f64,
    #[record(rec_name = "$(P)Current", rec_type = "ao")]
    #[record(field = "VAL")]
    current: f64,
    #[record(rec_name = "$(P)SlewRate", rec_type = "ao")]
    #[record(field = "VAL")]
    slew_rate: f64,
}

See tests for usage examples of other attributes.

Structs§

ParseError
Parser
Parser structure. It’s only purpose is to call parse and convert tables into a vector of user defined structs.
ParserBuilder
Builder for parsers.

Enums§

ParseErrorKind
The ParseError enum is a collection of all possible reasons a value could not be parsed.

Traits§

DataType
A trait to represent all different data types that can appear as a value in a worksheet cell
FromXlsxData
Interface that is used to convert XlsxData to target type.
FromXlsxRow
Interface that supports converting a single row in a table to a structure. This should be implemented from a derive macro FromXlsxRow!

Functions§

open_workbook
Convenient function to open a file with a BufReader

Type Aliases§

XlsxCell
A struct that represents an Excel Cell unit. Reexported from calamine.
XlsxData
A struct that represents a row in a table/sheet. Reexported from calamine.
XlsxRow
A struct that represents a row in a table/sheet. Reexported from calamine.
XlsxWorkbook

Derive Macros§

AsRecord
Implements as_record method for struct. See as_record attributes for attribute information.
FromXlsxFloat
Convenience macro that implements FromXlsxFloat for marked type. It is used to automatically define functions needed to convert calamine::Data::Float to target type.
FromXlsxRow
Convenience macro that implements FromXlsxRow for marked type. It is used to automatically convert XlsxRow (XlsxRow = Vec<calamine::Data>) to target type (usually a structure).
FromXlsxString
Convenience macro that implements FromXlsxString for marked type. It is used to automatically define functions needed to convert calamine::Data::String to target type.