use bytes::Bytes;
use serde::Serialize;
use serde_json::{json, Value};
use std::any::{Any, TypeId};
use super::JsonResponse;
pub trait ToBytes {
fn to_bytes(&self) -> Bytes;
}
impl ToBytes for () {
fn to_bytes(&self) -> Bytes {
Bytes::default()
}
}
impl ToBytes for Box<dyn ToBytes> {
fn to_bytes(&self) -> Bytes {
self.as_ref().to_bytes()
}
}
impl ToBytes for &'static str {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.as_bytes())
}
}
impl ToBytes for String {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_owned())
}
}
impl ToBytes for Bytes {
fn to_bytes(&self) -> Bytes {
self.clone()
}
}
impl ToBytes for i8 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for i16 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for i32 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for i64 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for i128 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for f32 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for f64 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for u8 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for u16 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for u32 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for u64 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for u128 {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for bool {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl ToBytes for Value {
fn to_bytes(&self) -> Bytes {
Bytes::from(self.to_string())
}
}
impl<T: Serialize + 'static> ToBytes for Vec<T> {
fn to_bytes(&self) -> Bytes {
let json = json!(self);
json.to_bytes()
}
}
impl<D: Serialize + 'static, E: Serialize + 'static> ToBytes for JsonResponse<D, E> {
fn to_bytes(&self) -> Bytes {
if let Some(data) = self.data() {
return json!({ "data": data }).to_bytes();
}
json!({ "error": self.error() }).to_bytes()
}
}
impl<T, E> ToBytes for Result<T, E>
where
T: ToBytes + Serialize + Any,
E: ToBytes + Serialize + Any,
{
fn to_bytes(&self) -> Bytes {
if TypeId::of::<E>() == TypeId::of::<Value>() && TypeId::of::<T>() == TypeId::of::<Value>()
{
match self {
Ok(value) => JsonResponse::<Value, Value>::new(Some(json!(value)), None).to_bytes(),
Err(error) => {
JsonResponse::<Value, Value>::new(None, Some(json!(error))).to_bytes()
}
}
} else {
match self {
Ok(value) => value.to_bytes(),
Err(error) => error.to_bytes(),
}
}
}
}
#[cfg(test)]
mod tests {
use std::f32::consts::PI;
use super::*;
#[test]
fn test_to_bytes_string() {
let input = "Hello, world!";
let expected = Bytes::from(input);
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_str() {
let input = "Hello, world!";
let expected = Bytes::from(input);
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_bytes() {
let input = Bytes::from("Hello, world!");
let expected = input.clone();
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_i32() {
let input = 42;
let expected = Bytes::from(input.to_string());
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_i64() {
let input = 42;
let expected = Bytes::from(input.to_string());
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_f32() {
let expected = Bytes::from(PI.to_string());
let result = PI.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_f64() {
let expected = Bytes::from(PI.to_string());
let result = PI.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_u32() {
let input = 42;
let expected = Bytes::from(input.to_string());
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_u64() {
let input = 42;
let expected = Bytes::from(input.to_string());
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_bool() {
let input = true;
let expected = Bytes::from(input.to_string());
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_value() {
let input = json!({ "key": "value" });
let expected = Bytes::from(input.to_string());
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_vec() {
let input = vec![1, 2, 3];
let expected = Bytes::from(json!(input).to_string());
let result = input.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_json_response_with_data() {
let data = json!({ "key": "value" });
let response: JsonResponse<Value, Value> = JsonResponse::new(Some(data.clone()), None);
let expected = Bytes::from(json!({ "data": data }).to_string());
let result = response.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_json_response_with_error() {
let error = json!({ "message": "Error occurred" });
let response: JsonResponse<Value, Value> = JsonResponse::new(None, Some(error.clone()));
let expected = Bytes::from(json!({ "error": error }).to_string());
let result = response.to_bytes();
assert_eq!(result, expected);
}
#[test]
fn test_to_bytes_result_json_result() {
let value = json!({ "key": "value" });
let result: Result<Value, Value> = Ok(value.clone());
let expected = Bytes::from(json!({ "data": value }).to_string());
let result_bytes = result.to_bytes();
assert_eq!(result_bytes, expected);
}
#[test]
fn test_to_bytes_result_json_result_error() {
let error = json!({ "message": "Error occurred" });
let result: Result<Value, Value> = Err(error.clone());
let expected = Bytes::from(json!({ "error": error }).to_string());
let result_bytes = result.to_bytes();
assert_eq!(result_bytes, expected);
}
#[test]
fn test_to_bytes_result_regular_result() {
let value = "Hello, world!";
let result: Result<&str, &str> = Ok(value);
let expected = Bytes::from(value);
let result_bytes = result.to_bytes();
assert_eq!(result_bytes, expected);
}
#[test]
fn test_to_bytes_result_regular_result_error() {
let error = "Error occurred";
let result: Result<&str, &str> = Err(error);
let expected = Bytes::from(error);
let result_bytes = result.to_bytes();
assert_eq!(result_bytes, expected);
}
}