rustolio-rpc 0.1.0

An RPC extention for the HTTP-Server
Documentation
//
// SPDX-License-Identifier: MPL-2.0
//
// Copyright (c) 2026 Tobias Binnewies. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

use rustolio_utils::{
    bytes::encoding::{decode_from_bytes, encode_to_bytes},
    http::{self, Outgoing, StatusCode},
    prelude::*,
};

use crate::ServerFnError;

// Called by the #[rpc] proc-macro
pub async fn fetch_rpc_call<T, R, E>(
    uri: &'static str,
    msg: T,
    before_fetch: fn(http::request::Builder<Outgoing>) -> http::request::Builder<Outgoing>,
) -> Result<R, ServerFnError<E>>
where
    T: Encode,
    R: Decode,
    E: Decode,
{
    let body =
        encode_to_bytes(&msg).map_err(|e| ServerFnError::SerializationError(e.to_string()))?;
    let req = http::Request::post(uri).bytes(&body);
    let req = before_fetch(req);
    let res = req
        .fetch()
        .await
        .map_err(|e| ServerFnError::NetworkError(e.to_string()))?;

    if !res.is_success() {
        let status = res.status();
        let text = res
            .text()
            .await
            .map_err(|e| ServerFnError::DeserializationError(e.to_string()))?
            .into_body();

        return Err(ServerFnError::HttpError(status, text));
    }

    let body = res
        .bytes()
        .await
        .map_err(|e| ServerFnError::NetworkError(e.to_string()))?
        .into_body();
    decode_from_bytes::<Result<_, _>>(body)
        .map_err(|e| ServerFnError::DeserializationError(e.to_string()))
        .flatten()
}