rustybook-messenger 0.2.1

Messenger client for Rustybook
Documentation
use serde_json::Value;

use crate::error::MessengerError;
use crate::gateway::lightspeed::envelope::Envelope;
use crate::gateway::lightspeed::payload::Payload;
use crate::gateway::lightspeed::req::ReqPayload;
use crate::gateway::lightspeed::request_id::RequestId;
use crate::gateway::lightspeed::resp::RespPayload;
use crate::gateway::lightspeed::sp::Sp;
use crate::gateway::lightspeed::topic::Topic;

pub fn decode_envelope(topic: &str, payload: &[u8]) -> Result<Envelope, MessengerError> {
    let topic = Topic::parse(topic);
    let raw: Value = serde_json::from_slice(payload)?;

    let request_id = RequestId::parse(raw.get("request_id").or_else(|| raw.get("requestId")));

    let sp = raw
        .get("sp")
        .and_then(Value::as_array)
        .map(|items| {
            items
                .iter()
                .filter_map(Value::as_str)
                .map(Sp::parse)
                .collect::<Vec<_>>()
        })
        .unwrap_or_default();

    let target = raw.get("target").and_then(Value::as_i64);

    let decoded_payload = match topic {
        Topic::LsReq => Payload::Request(ReqPayload::parse(raw.clone())),
        Topic::LsResp => {
            decode_response_payload(raw.get("payload")).map_or(Payload::Empty, Payload::Response)
        }
        _ => raw
            .get("payload")
            .cloned()
            .map(Payload::Json)
            .unwrap_or(Payload::Empty),
    };

    Ok(Envelope {
        topic,
        request_id,
        sp,
        target,
        payload: decoded_payload,
        raw,
    })
}

pub fn decode_request_payload(value: &Value) -> ReqPayload {
    ReqPayload::parse(value.clone())
}

pub fn decode_response_payload(value: Option<&Value>) -> Option<RespPayload> {
    let payload = match value {
        Some(Value::String(payload)) => serde_json::from_str::<Value>(payload).ok()?,
        Some(payload) => payload.clone(),
        None => return None,
    };

    RespPayload::parse(payload)
}

pub fn encode_request(payload: &ReqPayload) -> Result<Vec<u8>, MessengerError> {
    let value = payload.to_json();
    Ok(serde_json::to_vec(&value)?)
}