// Copyright 2019-2023 Tauri Programme within The Commons Conservancy // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT use serde::{Deserialize, Serialize, Serializer}; use std::fmt::Display; /// Arguments of the [`Nfc::scan`](crate::Nfc::scan) API. #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct ScanRequest { /// The kind of scan to perform, which defines how tags are matched. pub kind: ScanKind, /// Whether the connection to the scanned tag must be kept open after the scan resolves. /// /// When `true`, a following [`Nfc::write`](crate::Nfc::write) call writes to the tag that was /// scanned instead of starting a new session. pub keep_session_alive: bool, } /// An NDEF record to be written to a tag. /// /// Use [`NFCTypeNameFormat`] to describe how [`Self::kind`] must be interpreted. #[derive(Serialize)] #[serde(rename_all = "camelCase")] pub struct NfcRecord { /// The Type Name Format (TNF) of the record. pub format: NFCTypeNameFormat, /// The record type, interpreted according to [`Self::format`]. /// /// For [`NFCTypeNameFormat::NfcWellKnown`] records this is a Record Type Definition (RTD) /// value such as `[0x54]` (`RTD_TEXT`) or `[0x55]` (`RTD_URI`). pub kind: Vec, /// The record identifier. Can be empty. pub id: Vec, /// The record payload bytes. pub payload: Vec, } /// The Type Name Format (TNF) of an NDEF record, which defines how the record type is interpreted. /// /// Serialized as its numeric value. #[derive(serde_repr::Deserialize_repr, serde_repr::Serialize_repr)] #[repr(u8)] pub enum NFCTypeNameFormat { /// The record is empty: type, identifier and payload must be empty. Empty = 0, /// The record type is an NFC Forum well known type, defined by a Record Type Definition (RTD) /// such as `RTD_TEXT` (`[0x54]`) or `RTD_URI` (`[0x55]`). NfcWellKnown = 1, /// The record type is a MIME media type as defined in RFC 2046, e.g. `text/plain`. Media = 2, /// The record type is an absolute URI as defined in RFC 3986. AbsoluteURI = 3, /// The record type is an NFC Forum external type, i.e. a type namespaced by its issuer. NfcExternal = 4, /// The record type is unknown: the type must be empty and the payload interpretation is /// left to the application. Unknown = 5, /// The record is a middle or last chunk of a chunked record and inherits the type of the /// first chunk, so its own type must be empty. Unchanged = 6, } /// An NDEF record read from a scanned tag. #[derive(Deserialize)] pub struct NfcTagRecord { /// The Type Name Format (TNF) of the record, which defines how [`Self::kind`] is interpreted. pub tnf: NFCTypeNameFormat, /// The record type bytes. pub kind: Vec, /// The record identifier bytes. Can be empty. pub id: Vec, /// The record payload bytes. pub payload: Vec, } /// An NFC tag that has been scanned. #[derive(Deserialize)] pub struct NfcTag { /// The tag identifier, as reported by the operating system. pub id: String, /// The technology the tag supports. pub kind: String, /// The NDEF records stored on the tag. Empty when the tag holds no NDEF message. pub records: Vec, } /// Response of the [`Nfc::scan`](crate::Nfc::scan) API. #[derive(Deserialize)] pub struct ScanResponse { /// The tag that has been scanned. pub tag: NfcTag, } /// Filters the tags to scan by the URI of their NDEF payload. /// /// Every field is optional and only the ones that are set take part in the filter. /// **Android only**: the iOS implementation ignores this filter. #[derive(Debug, Default, Serialize)] pub struct UriFilter { /// Only match URIs with this scheme, e.g. `https`. scheme: Option, /// Only match URIs with this authority (host), e.g. `tauri.app`. host: Option, /// Only match URIs whose path starts with this prefix, e.g. `/docs`. path_prefix: Option, } /// The NFC technologies a tag can support, mirroring the `android.nfc.tech` classes. /// /// **Android only**. Serialized as the technology name, e.g. `"IsoDep"`. #[derive(Debug)] pub enum TechKind { /// ISO-DEP (ISO 14443-4) properties and I/O operations. IsoDep, /// MIFARE Classic properties and I/O operations. MifareClassic, /// MIFARE Ultralight and MIFARE Ultralight C properties and I/O operations. MifareUltralight, /// NDEF data and operations on tags that are already formatted as NDEF. Ndef, /// Formatting operations on tags that can be formatted as NDEF but are not yet. NdefFormatable, /// NFC-A (ISO 14443-3A) properties and I/O operations. NfcA, /// NFC-B (ISO 14443-3B) properties and I/O operations. NfcB, /// NFC Barcode (Kovio NFC Barcode) properties and I/O operations. NfcBarcode, /// NFC-F (JIS 6319-4) properties and I/O operations. NfcF, /// NFC-V (ISO 15693) properties and I/O operations. NfcV, } impl Display for TechKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "{}", match self { Self::IsoDep => "IsoDep", Self::MifareClassic => "MifareClassic", Self::MifareUltralight => "MifareUltralight", Self::Ndef => "Ndef", Self::NdefFormatable => "NdefFormatable", Self::NfcA => "NfcA", Self::NfcB => "NfcB", Self::NfcBarcode => "NfcBarcode", Self::NfcF => "NfcF", Self::NfcV => "NfcV", } ) } } impl Serialize for TechKind { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&self.to_string()) } } /// The kind of scan to perform, which defines which tags are matched. #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub enum ScanKind { /// Only match tags that carry an NDEF message. Ndef { /// Only match tags whose NDEF payload has this MIME type, e.g. `text/plain`. /// **Android only**. mime_type: Option, /// Only match tags whose NDEF payload URI matches this filter. **Android only**. uri: Option, /// Only match tags supporting the listed technologies. /// /// Each tech list is considered independently and the tag matches when any single tech /// list matches it, which provides AND (inside a list) and OR (between lists) semantics. /// /// **Android only**. See /// /// for more information. tech_list: Option>>, }, /// Match any tag that is discovered, whether it carries an NDEF message or not. Tag { /// Only match tags whose payload has this MIME type, e.g. `text/plain`. **Android only**. mime_type: Option, /// Only match tags whose payload URI matches this filter. **Android only**. uri: Option, }, }