Skip to content

Commit

Permalink
Add MessagePack codec (#2371)
Browse files Browse the repository at this point in the history
* feat: added messagepack codec

* fix: deserialize msgpack from bytes, not string
  • Loading branch information
johnbchron authored Mar 3, 2024
1 parent 4bb43f6 commit 530087d
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
2 changes: 2 additions & 0 deletions server_fn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ rkyv = { version = "0.7", features = [
"uuid",
"strict",
], optional = true }
rmp-serde = { version = "1.1", optional = true }

# client
gloo-net = { version = "0.5", optional = true }
Expand Down Expand Up @@ -102,6 +103,7 @@ multipart = ["browser", "dep:multer"]
url = ["dep:serde_qs"]
cbor = ["dep:ciborium"]
rkyv = ["dep:rkyv"]
msgpack = ["dep:rmp-serde"]
default-tls = ["reqwest?/default-tls"]
rustls = ["reqwest?/rustls-tls"]
reqwest = ["dep:reqwest"]
Expand Down
5 changes: 5 additions & 0 deletions server_fn/src/codec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ mod multipart;
#[cfg(feature = "multipart")]
pub use multipart::*;

#[cfg(feature = "msgpack")]
mod msgpack;
#[cfg(feature = "msgpack")]
pub use msgpack::*;

mod stream;
use crate::error::ServerFnError;
use futures::Future;
Expand Down
74 changes: 74 additions & 0 deletions server_fn/src/codec/msgpack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use super::{Encoding, FromReq, FromRes, IntoReq, IntoRes};
use crate::{
error::ServerFnError,
request::{ClientReq, Req},
response::{ClientRes, Res},
};
use bytes::Bytes;
use http::Method;
use serde::{de::DeserializeOwned, Serialize};

/// A codec for MessagePack.
pub struct MsgPack;

impl Encoding for MsgPack {
const CONTENT_TYPE: &'static str = "application/msgpack";
const METHOD: Method = Method::POST;
}

impl<T, Request, Err> IntoReq<MsgPack, Request, Err> for T
where
Request: ClientReq<Err>,
T: Serialize,
{
fn into_req(
self,
path: &str,
accepts: &str,
) -> Result<Request, ServerFnError<Err>> {
let data = rmp_serde::to_vec(&self)
.map_err(|e| ServerFnError::Serialization(e.to_string()))?;
Request::try_new_post_bytes(
path,
MsgPack::CONTENT_TYPE,
accepts,
Bytes::from(data),
)
}
}

impl<T, Request, Err> FromReq<MsgPack, Request, Err> for T
where
Request: Req<Err> + Send,
T: DeserializeOwned,
{
async fn from_req(req: Request) -> Result<Self, ServerFnError<Err>> {
let data = req.try_into_bytes().await?;
rmp_serde::from_slice::<T>(&data)
.map_err(|e| ServerFnError::Args(e.to_string()))
}
}

impl<T, Response, Err> IntoRes<MsgPack, Response, Err> for T
where
Response: Res<Err>,
T: Serialize + Send,
{
async fn into_res(self) -> Result<Response, ServerFnError<Err>> {
let data = rmp_serde::to_vec(&self)
.map_err(|e| ServerFnError::Serialization(e.to_string()))?;
Response::try_from_bytes(MsgPack::CONTENT_TYPE, Bytes::from(data))
}
}

impl<T, Response, Err> FromRes<MsgPack, Response, Err> for T
where
Response: ClientRes<Err> + Send,
T: DeserializeOwned,
{
async fn from_res(res: Response) -> Result<Self, ServerFnError<Err>> {
let data = res.try_into_bytes().await?;
rmp_serde::from_slice(&data)
.map_err(|e| ServerFnError::Deserialization(e.to_string()))
}
}

0 comments on commit 530087d

Please sign in to comment.