use serde::{Deserialize, Serialize};
use crate::device::WedgeScan;
use crate::ids::DeviceId;
use crate::nfc::{NdefRecord, NfcReading};
use crate::registry::DeviceSummary;
use crate::Bytes;
pub const BRIDGE_VERSION: u8 = 1;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
pub struct ClientFrame {
pub v: u8,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "ts", ts(optional))]
pub id: Option<String>,
#[serde(flatten)]
#[cfg_attr(feature = "ts", ts(flatten))]
pub message: ClientMessage,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
#[serde(tag = "type", rename_all = "kebab-case")]
pub enum ClientMessage {
#[serde(rename_all = "camelCase")]
Hello {
origin: String,
shim_version: String,
apis: Vec<String>,
},
#[serde(rename_all = "camelCase")]
Open {
device_id: DeviceId,
#[serde(default)]
options: serde_json::Value,
},
#[serde(rename_all = "camelCase")]
Close {
device_id: DeviceId,
},
#[serde(rename_all = "camelCase")]
Signals {
device_id: DeviceId,
signals: SerialSignals,
},
#[serde(rename_all = "camelCase")]
Write {
device_id: DeviceId,
#[serde(with = "crate::base64::serde_bytes")]
#[cfg_attr(feature = "ts", ts(type = "string"))]
data: Bytes,
},
#[serde(rename_all = "camelCase")]
NfcWrite {
device_id: DeviceId,
records: Vec<NdefRecord>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "ts", ts(optional))]
overwrite: Option<bool>,
},
#[serde(rename_all = "camelCase")]
NfcMakeReadOnly {
device_id: DeviceId,
},
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
#[serde(rename_all = "camelCase")]
pub struct SerialSignals {
#[serde(default, skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "ts", ts(optional))]
pub data_terminal_ready: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "ts", ts(optional))]
pub request_to_send: Option<bool>,
#[serde(rename = "break", default, skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "ts", ts(rename = "break", optional))]
pub brk: Option<bool>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
pub struct ServerFrame {
pub v: u8,
#[serde(flatten)]
#[cfg_attr(feature = "ts", ts(flatten))]
pub message: ServerMessage,
}
impl ServerFrame {
pub fn new(message: ServerMessage) -> Self {
Self {
v: BRIDGE_VERSION,
message,
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
#[serde(tag = "type", rename_all = "kebab-case")]
pub enum ServerMessage {
Devices {
devices: Vec<DeviceSummary>,
},
#[serde(rename_all = "camelCase")]
Ack {
reply_to: String,
},
#[serde(rename_all = "camelCase")]
Data {
device_id: DeviceId,
#[serde(with = "crate::base64::serde_bytes")]
#[cfg_attr(feature = "ts", ts(type = "string"))]
data: Bytes,
},
#[serde(rename_all = "camelCase")]
Connect {
device_id: DeviceId,
},
#[serde(rename_all = "camelCase")]
Disconnect {
device_id: DeviceId,
},
#[serde(rename_all = "camelCase")]
WedgeScan {
device_id: DeviceId,
#[serde(flatten)]
#[cfg_attr(feature = "ts", ts(flatten))]
scan: WedgeScan,
},
#[serde(rename_all = "camelCase")]
NfcReading {
device_id: DeviceId,
#[serde(flatten)]
#[cfg_attr(feature = "ts", ts(flatten))]
reading: NfcReading,
},
#[serde(rename_all = "camelCase")]
NfcError {
device_id: DeviceId,
#[serde(flatten)]
#[cfg_attr(feature = "ts", ts(flatten))]
reading: NfcReading,
},
#[serde(rename_all = "camelCase")]
Error {
code: BridgeErrorCode,
message: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "ts", ts(optional))]
reply_to: Option<String>,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "ts", derive(ts_rs::TS))]
#[serde(rename_all = "snake_case")]
pub enum BridgeErrorCode {
NotFound,
Network,
InvalidState,
NotAllowed,
BadMessage,
Unauthorized,
Internal,
}