ados-protocol 0.106.2

Wire contracts for the ADOS Drone Agent: length-prefixed IPC framing, plugin RPC envelope and capability tokens, the vision frame bus, MSP and MAVLink helpers.
Documentation
//! Process-wide rustls crypto provider install.
//!
//! The workspace's reqwest is unified onto the no-provider rustls path
//! (ados-cloud hands every client it builds a preconfigured config). A reqwest
//! `Client::builder().build()` that does not supply a preconfigured TLS config
//! constructs a DEFAULT config, which needs a process-default crypto provider —
//! without one it panics "No provider set", non-deterministically under
//! concurrent first builds. Every bare reqwest client builder in the agent calls
//! [`ensure_crypto_provider`] first so the install is deterministic + race-free.

use std::sync::Once;

/// Install the ring rustls provider as the process default, exactly once.
/// An `Err` from `install_default` means a provider is already installed (e.g.
/// a preconfigured-TLS client beat us to it), which is fine.
pub fn ensure_crypto_provider() {
    static INIT: Once = Once::new();
    INIT.call_once(|| {
        let _ = rustls::crypto::ring::default_provider().install_default();
    });
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn ensure_is_idempotent_and_installs_a_default() {
        // Calling it (possibly after another crate already installed a provider)
        // must never panic, a second call is a no-op, and afterwards a default
        // provider is present for a bare client builder to find.
        ensure_crypto_provider();
        ensure_crypto_provider();
        assert!(rustls::crypto::CryptoProvider::get_default().is_some());
    }
}