feat: generate typed frontend API contracts
This commit is contained in:
@@ -14,5 +14,6 @@ serde_json = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
flate2 = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
ts-rs = { version = "12.0.1", features = ["uuid-impl"] }
|
||||
sgp4 = "2"
|
||||
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] }
|
||||
|
||||
@@ -3,13 +3,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
|
||||
const SPEED_OF_LIGHT_M_PER_S: f64 = 299_792_458.0;
|
||||
|
||||
/// Supported band range in Hz.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TS)]
|
||||
pub struct Band {
|
||||
#[ts(type = "number")]
|
||||
pub low_hz: u64,
|
||||
#[ts(type = "number")]
|
||||
pub high_hz: u64,
|
||||
pub tx_allowed: bool,
|
||||
}
|
||||
@@ -23,8 +26,9 @@ impl Band {
|
||||
}
|
||||
|
||||
/// Frequency wrapper (Hz).
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, TS)]
|
||||
pub struct Freq {
|
||||
#[ts(type = "number")]
|
||||
pub hz: u64,
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::radio::freq::{Band, Freq};
|
||||
use crate::{DynResult, RigMode};
|
||||
@@ -21,14 +22,14 @@ pub mod response;
|
||||
pub mod state;
|
||||
|
||||
/// How this backend communicates with the rig.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TS)]
|
||||
pub enum RigAccessMethod {
|
||||
Serial { path: String, baud: u32 },
|
||||
Tcp { addr: String },
|
||||
}
|
||||
|
||||
/// Static info describing a rig backend.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigInfo {
|
||||
pub manufacturer: String,
|
||||
pub model: String,
|
||||
@@ -37,9 +38,10 @@ pub struct RigInfo {
|
||||
pub access: RigAccessMethod,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TS)]
|
||||
pub struct RigCapabilities {
|
||||
#[serde(default = "default_min_freq_step_hz")]
|
||||
#[ts(type = "number")]
|
||||
pub min_freq_step_hz: u64,
|
||||
pub supported_bands: Vec<Band>,
|
||||
pub supported_modes: Vec<RigMode>,
|
||||
@@ -314,7 +316,7 @@ pub trait RigSdr: Send {
|
||||
}
|
||||
|
||||
/// Snapshot of a rig's status that every backend can expose.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigStatus {
|
||||
pub freq: Freq,
|
||||
pub mode: RigMode,
|
||||
@@ -330,21 +332,21 @@ pub trait RigStatusProvider {
|
||||
fn status(&self) -> RigStatus;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigVfo {
|
||||
pub entries: Vec<RigVfoEntry>,
|
||||
/// Index into `entries` for the active VFO, if known.
|
||||
pub active: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigVfoEntry {
|
||||
pub name: String,
|
||||
pub freq: Freq,
|
||||
pub mode: Option<RigMode>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigTxStatus {
|
||||
pub power: Option<u8>,
|
||||
pub limit: Option<u8>,
|
||||
@@ -352,7 +354,7 @@ pub struct RigTxStatus {
|
||||
pub alc: Option<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigRxStatus {
|
||||
pub sig: Option<f64>,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::radio::freq::Freq;
|
||||
@@ -12,7 +13,7 @@ use crate::rig::{RigControl, RigInfo, RigRxStatus, RigStatus, RigStatusProvider,
|
||||
///
|
||||
/// Flattened into `RigState` and `RigSnapshot` so the JSON wire format is
|
||||
/// unchanged (backward compatible with existing clients).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default, TS)]
|
||||
pub struct DecoderConfig {
|
||||
#[serde(default)]
|
||||
pub aprs_decode_enabled: bool,
|
||||
@@ -113,7 +114,7 @@ pub struct RigState {
|
||||
}
|
||||
|
||||
/// Mode supported by the rig.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TS)]
|
||||
pub enum RigMode {
|
||||
LSB,
|
||||
USB,
|
||||
@@ -315,7 +316,7 @@ impl RigState {
|
||||
}
|
||||
|
||||
/// Current filter/DSP state for backends that support runtime filter adjustment.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigFilterState {
|
||||
pub bandwidth_hz: u32,
|
||||
pub cw_center_hz: u32,
|
||||
@@ -355,7 +356,7 @@ pub struct RigFilterState {
|
||||
pub sam_carrier_sync: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, TS)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum WfmDenoiseLevel {
|
||||
Off,
|
||||
@@ -386,11 +387,12 @@ fn default_wfm_denoise_level() -> WfmDenoiseLevel {
|
||||
}
|
||||
|
||||
/// Spectrum data from SDR backends (FFT magnitude over the full capture bandwidth).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct SpectrumData {
|
||||
/// FFT magnitude bins in dBFS, FFT-shifted so DC (centre frequency) is at index N/2.
|
||||
pub bins: Vec<f32>,
|
||||
/// Centre frequency of the SDR capture in Hz.
|
||||
#[ts(type = "number")]
|
||||
pub center_hz: u64,
|
||||
/// SDR capture sample rate in Hz; the displayed span is ±sample_rate/2.
|
||||
pub sample_rate: u32,
|
||||
@@ -400,7 +402,7 @@ pub struct SpectrumData {
|
||||
}
|
||||
|
||||
/// Live RDS metadata decoded from a WFM broadcast.
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RdsData {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub pi: Option<u16>,
|
||||
@@ -437,7 +439,7 @@ pub struct RdsData {
|
||||
/// `PartialEq` intentionally ignores `signal_db` so that rapidly-changing
|
||||
/// signal levels do not cause the main state snapshot to diff on every poll
|
||||
/// cycle (signal_db flows through the spectrum SSE instead).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct VchanRdsEntry {
|
||||
/// Virtual channel UUID.
|
||||
pub id: Uuid,
|
||||
@@ -456,7 +458,7 @@ impl PartialEq for VchanRdsEntry {
|
||||
}
|
||||
|
||||
/// Read-only projection of state shared with clients.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct RigSnapshot {
|
||||
pub info: RigInfo,
|
||||
pub status: RigStatus,
|
||||
|
||||
Reference in New Issue
Block a user