Skip to main content

uls_core/records/
frequency.rs

1//! FR (Frequency) record type - Frequency assignment data.
2
3use serde::{Deserialize, Serialize};
4
5use super::common::*;
6
7/// FR record - Frequency data.
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct FrequencyRecord {
10    pub unique_system_identifier: i64,
11    pub uls_file_number: Option<String>,
12    pub ebf_number: Option<String>,
13    pub call_sign: Option<String>,
14    pub frequency_action_performed: Option<char>,
15    pub location_number: Option<i32>,
16    pub antenna_number: Option<i32>,
17    pub class_station_code: Option<String>,
18    pub op_altitude_code: Option<String>,
19    pub frequency_assigned: Option<f64>,
20    pub frequency_upper_band: Option<f64>,
21    pub frequency_carrier: Option<f64>,
22    pub time_begin_operations: Option<i32>,
23    pub time_end_operations: Option<i32>,
24    pub power_output: Option<f64>,
25    pub power_erp: Option<f64>,
26    pub tolerance: Option<f64>,
27    pub frequency_ind: Option<char>,
28    pub status: Option<char>,
29    pub eirp: Option<f64>,
30    pub transmitter_make: Option<String>,
31    pub transmitter_model: Option<String>,
32    pub auto_transmitter_power_control: Option<char>,
33    pub cnt_mobile_units: Option<i32>,
34    pub cnt_mob_pagers: Option<i32>,
35    pub freq_seq_id: Option<i32>,
36    pub status_code: Option<char>,
37    pub status_date: Option<String>,
38    pub date_first_used: Option<String>,
39}
40
41impl FrequencyRecord {
42    /// Parse a frequency record from pipe-delimited fields.
43    pub fn from_fields(fields: &[&str]) -> Self {
44        Self {
45            unique_system_identifier: parse_i64_or_default(fields.get(1).unwrap_or(&"")),
46            uls_file_number: parse_opt_string(fields.get(2).unwrap_or(&"")),
47            ebf_number: parse_opt_string(fields.get(3).unwrap_or(&"")),
48            call_sign: parse_opt_string(fields.get(4).unwrap_or(&"")),
49            frequency_action_performed: parse_opt_char(fields.get(5).unwrap_or(&"")),
50            location_number: parse_opt_i32(fields.get(6).unwrap_or(&"")),
51            antenna_number: parse_opt_i32(fields.get(7).unwrap_or(&"")),
52            class_station_code: parse_opt_string(fields.get(8).unwrap_or(&"")),
53            op_altitude_code: parse_opt_string(fields.get(9).unwrap_or(&"")),
54            frequency_assigned: parse_opt_f64(fields.get(10).unwrap_or(&"")),
55            frequency_upper_band: parse_opt_f64(fields.get(11).unwrap_or(&"")),
56            frequency_carrier: parse_opt_f64(fields.get(12).unwrap_or(&"")),
57            time_begin_operations: parse_opt_i32(fields.get(13).unwrap_or(&"")),
58            time_end_operations: parse_opt_i32(fields.get(14).unwrap_or(&"")),
59            power_output: parse_opt_f64(fields.get(15).unwrap_or(&"")),
60            power_erp: parse_opt_f64(fields.get(16).unwrap_or(&"")),
61            tolerance: parse_opt_f64(fields.get(17).unwrap_or(&"")),
62            frequency_ind: parse_opt_char(fields.get(18).unwrap_or(&"")),
63            status: parse_opt_char(fields.get(19).unwrap_or(&"")),
64            eirp: parse_opt_f64(fields.get(20).unwrap_or(&"")),
65            transmitter_make: parse_opt_string(fields.get(21).unwrap_or(&"")),
66            transmitter_model: parse_opt_string(fields.get(22).unwrap_or(&"")),
67            auto_transmitter_power_control: parse_opt_char(fields.get(23).unwrap_or(&"")),
68            cnt_mobile_units: parse_opt_i32(fields.get(24).unwrap_or(&"")),
69            cnt_mob_pagers: parse_opt_i32(fields.get(25).unwrap_or(&"")),
70            freq_seq_id: parse_opt_i32(fields.get(26).unwrap_or(&"")),
71            status_code: parse_opt_char(fields.get(27).unwrap_or(&"")),
72            status_date: parse_opt_string(fields.get(28).unwrap_or(&"")),
73            date_first_used: parse_opt_string(fields.get(29).unwrap_or(&"")),
74        }
75    }
76
77    /// Returns the frequency in MHz.
78    pub fn frequency_mhz(&self) -> Option<f64> {
79        self.frequency_assigned
80    }
81
82    /// Returns the frequency in kHz.
83    pub fn frequency_khz(&self) -> Option<f64> {
84        self.frequency_assigned.map(|f| f * 1000.0)
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn test_frequency_from_fields() {
94        let fields: Vec<&str> = vec![
95            "FR",
96            "123456789",
97            "",
98            "",
99            "W1AW",
100            "",
101            "1",
102            "1",
103            "FB",
104            "",
105            "146.94000000",
106            "",
107            "",
108            "0",
109            "2400",
110            "50.0",
111            "",
112            "",
113            "",
114            "",
115            "",
116            "",
117            "",
118            "",
119            "",
120            "",
121            "",
122            "",
123            "",
124        ];
125        let record = FrequencyRecord::from_fields(&fields);
126        assert_eq!(record.unique_system_identifier, 123456789);
127        assert!((record.frequency_assigned.unwrap() - 146.94).abs() < 0.001);
128    }
129}