pub trait LinkTransport: Send + Sync {
// Required method
fn post(
&self,
endpoint: &str,
path: &str,
message: &Signed,
) -> Result<LinkReply, String>;
}Expand description
How a link message reaches a peer. The domain above never names a socket: the HTTP adapter is the one the shared server answers, and a test can put two runtimes in one process behind another adapter without changing a line of protocol.
One method is the whole contract, which is what keeps the protocol testable: the authenticity of a link comes from the signatures inside the messages, never from the channel, so an implementation owes nothing but delivery.
use majordomus_cli::mesh::link::{LinkReply, LinkTransport, RefusalCode, Signed, HELLO_PATH};
// an adapter that reaches nobody is still a transport; it refuses nothing, it fails
struct Unplugged;
impl LinkTransport for Unplugged {
fn post(&self, endpoint: &str, _path: &str, _message: &Signed) -> Result<LinkReply, String> {
Err(format!("{endpoint}: no network here"))
}
}
let signed = Signed { body: serde_json::json!({}), sig: String::new() };
let error = Unplugged.post("10.0.0.2:8742", HELLO_PATH, &signed).unwrap_err();
assert!(error.contains("10.0.0.2:8742"), "a failure names where it was going");
// a refusal, by contrast, is a reply that arrived
let refusal = LinkReply::refused(RefusalCode::Untrusted, "not in the allowlist");
assert!(refusal.refusal.is_some());Required Methods§
Sourcefn post(
&self,
endpoint: &str,
path: &str,
message: &Signed,
) -> Result<LinkReply, String>
fn post( &self, endpoint: &str, path: &str, message: &Signed, ) -> Result<LinkReply, String>
Post message to path at endpoint (host:port) and return the peer’s reply.
Err is a transport failure — unreachable, timed out, not a reply — never a
refusal; a refusal is an Ok reply that says so.
The distinction is what the caller acts on: a transport failure is a peer to back off from and try again later, while a refusal is a decision that will be made the same way next time and is recorded instead of retried.
use majordomus_cli::mesh::link::{HttpTransport, LinkTransport, Signed, HELLO_PATH};
let signed = Signed { body: serde_json::json!({}), sig: String::new() };
// port 9 discards: unreachable is a transport failure, not a refusal
let error = HttpTransport.post("127.0.0.1:9", HELLO_PATH, &signed).unwrap_err();
assert!(error.contains("127.0.0.1:9"), "{error}");Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".