dink-sdk 0.3.1

Rust SDK for Dink edge mesh platform — JSON-over-NATS RPC for IoT and edge computing
Documentation
use async_nats::Client;
use serde::Deserialize;
use serde_json::json;
use std::collections::HashMap;
use std::time::Duration;

use crate::error::Result;
use crate::internal::envelope::parse_platform_response;
use crate::internal::nats::request_with_auth;

#[derive(Debug, Deserialize)]
pub struct RegisterResponse {
    pub groups: Option<Vec<String>>,
}

/// Register this edge with the platform presence system.
///
/// Returns the list of groups the edge belongs to.
pub async fn register_presence(
    client: &Client,
    api_key: &str,
    name: &str,
    labels: &HashMap<String, String>,
    version: &str,
    hostname: &str,
    ip_address: &str,
) -> Result<Vec<String>> {
    let body = json!({
        "name": name,
        "type": "lite",
        "labels": labels,
        "version": version,
        "hostname": hostname,
        "ip_address": ip_address,
    });
    let data = serde_json::to_vec(&body)?;
    let resp = request_with_auth(
        client,
        "$EDGE.PRESENCE.REGISTER",
        &data,
        api_key,
        Duration::from_secs(5),
    )
    .await?;
    let reg: RegisterResponse = parse_platform_response(&resp.payload)?;
    Ok(reg.groups.unwrap_or_default())
}

/// Deregister from the platform presence system.
///
/// Best-effort — errors are silently ignored so this never blocks shutdown.
pub async fn deregister_presence(client: &Client, api_key: &str) -> Result<()> {
    let _ = request_with_auth(
        client,
        "$EDGE.PRESENCE.DEREGISTER",
        b"{}",
        api_key,
        Duration::from_secs(2),
    )
    .await;
    Ok(())
}

/// Fire-and-forget heartbeat with Authorization header.
pub async fn send_heartbeat(client: &Client, api_key: &str) {
    let mut headers = async_nats::HeaderMap::new();
    headers.insert("Authorization", format!("Bearer {}", api_key).as_str());
    // Best-effort: ignore publish errors on heartbeat.
    let _ = client
        .publish_with_headers(
            "$EDGE.PRESENCE.HEARTBEAT".to_string(),
            headers,
            bytes::Bytes::from_static(b"{}"),
        )
        .await;
}