pub fn negotiate_downstream(
params: &JsonObject,
upstream: &Leg,
config: &DownstreamConfig,
) -> Result<Downstream, DownstreamError>Expand description
Settles the downstream leg of a handshake.
Re-exported beside the rest so the two halves of a bridge’s negotiation are
reachable together: this needs an upstream Agreement,
which is what the client half of the connection produced.
Settles the downstream leg against an already-negotiated upstream.
Reads the client’s offer with the same code a server uses, so a bridge and
a server cannot disagree about what a client is allowed to say, then
reconciles the two legs through Agreement::between.
The two things returned are not two views of one value. The Agreement is
what the bridge may forward; the body is the wire form of it. A caller that
forwarded against the downstream Leg alone would be forwarding features it
had just told the client it does not have.
Takes the upstream as a Leg rather than an Agreement because that is
all it is: the upstream negotiated with the server when the bridge connected,
and the client that will supply the other leg has not arrived yet. Accepting
an Agreement would have asked the caller to invent a downstream leg they do
not have, and every invented leg is one more place the served profile can
disagree with the advertised one.
§Errors
DownstreamError::Malformed for an initialize that is not an offer, and
DownstreamError::NoHandshake if there is no revision with a handshake to
answer with.
§Examples
use protocol_droid::application::bridge::{negotiate_downstream, DownstreamConfig};
use protocol_droid::domain::ir::JsonObject;
use protocol_droid::domain::{FeatureProfile, Leg, ProtocolVersion, TransportKind};
let config = DownstreamConfig::new("bridge", "0.1.0", TransportKind::Stdio)?;
let params = JsonObject::new(
r#"{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe"}}"#,
)?;
let downstream = negotiate_downstream(¶ms, &upstream, &config)?;
// The advertisement is the agreement, never the client's own leg.
assert_eq!(downstream.served(), downstream.agreement().served());