Skip to main content

navcore_signalk_client/
lib.rs

1//! The wire to a Signal K server.
2//!
3//! This crate handles everything that touches the network. [`signalk`]
4//! reads a delta and reconciles sources as a pure function of what it
5//! is handed; this crate finds a server, gets let in, and keeps the
6//! socket open.
7//!
8//! The separation lets the delta reader, the unit conversions and the
9//! handover between two position sources be tested without a boat, a
10//! network or a server, and lets a recorded passage be replayed through
11//! exactly the code that sailed it.
12//!
13//! # The three steps
14//!
15//! [`discovery`] listens for servers announcing themselves over mDNS.
16//! The announcement carries the vessel's own identifier, so nothing has
17//! to be configured by hand.
18//!
19//! [`access`] asks for a token and waits for a human to approve it,
20//! once. [`token`] reads what an approved token says about itself; a
21//! token already held is read again on every start, independent of the
22//! request that won it.
23//!
24//! [`stream`] opens the data stream and keeps it open, reconnecting for
25//! as long as it is asked to. Failure is reported as a state, not as an
26//! error to abort on: when a wireless link on a boat drops, the fix
27//! goes visibly stale rather than the connection stopping.
28
29#![forbid(unsafe_code)]
30
31pub mod access;
32pub mod anchor;
33pub mod course;
34pub mod discovery;
35pub mod onboard;
36pub mod resources;
37pub mod server_info;
38pub mod stream;
39pub mod token;
40pub mod trust;
41pub mod units;
42
43pub use access::{Access, PendingRequest, Permissions, Requested, check_access, request_access};
44pub use discovery::{Discovery, Server, discover, resolve_stated_server};
45pub use onboard::{Credentials, Link, Onboard, Onboarding, Stage};
46pub use server_info::{fetch as fetch_server_info, ServerInfo};
47pub use units::fetch_active as fetch_active_units;
48pub use stream::{Connection, Event};
49pub use token::Token;
50pub use trust::Trust;
51
52/// Anything that can go wrong on the way to a server.
53#[derive(Debug)]
54pub enum ClientError {
55    /// The mDNS browse could not be started.
56    Discovery(String),
57    /// The server could not be reached, or refused.
58    Http(String),
59    /// The server answered something this client cannot read.
60    Protocol(String),
61    /// The boat's authority could not be read, or could not be used.
62    Trust(String),
63}
64
65impl std::fmt::Display for ClientError {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        match self {
68            Self::Discovery(detail) => write!(f, "looking for a server: {detail}"),
69            Self::Http(detail) => write!(f, "talking to the server: {detail}"),
70            Self::Protocol(detail) => write!(f, "unexpected answer: {detail}"),
71            Self::Trust(detail) => write!(f, "deciding whom to trust: {detail}"),
72        }
73    }
74}
75
76impl std::error::Error for ClientError {}