Skip to main content

qubit_codec/value/
json_bytes_value_codec.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Bidirectional Serde JSON bytes codec for one owned value.
9
10use core::marker::PhantomData;
11
12use serde::Serialize;
13use serde::de::DeserializeOwned;
14use serde_json::Error as JsonError;
15
16use super::JsonBytesValueDecoder;
17use super::JsonBytesValueEncoder;
18use super::ValueDecoder;
19use super::ValueEncoder;
20
21/// Encodes and decodes one serializable value through UTF-8 JSON bytes.
22///
23/// This type combines [`JsonBytesValueEncoder`] and [`JsonBytesValueDecoder`]
24/// for registry-backed or bidirectional call sites. It holds no state between
25/// calls, so it is `Copy` and `Default`, and encoding and decoding can share
26/// one value through [`ValueEncoder`] and [`ValueDecoder`].
27///
28/// # Type Parameters
29///
30/// - `T`: Value type serialized to JSON bytes and recovered from them.
31///
32/// # Examples
33///
34/// ```
35/// use qubit_codec::JsonBytesValueCodec;
36/// use qubit_codec::ValueDecoder;
37/// use qubit_codec::ValueEncoder;
38///
39/// let mut codec = JsonBytesValueCodec::<String>::new();
40/// assert_eq!(codec.encode(&"hello".to_string()).unwrap(), br#""hello""#.to_vec());
41/// assert_eq!(codec.decode(br#""hello""#).unwrap(), "hello");
42/// ```
43#[must_use]
44#[derive(Debug, Clone, Copy, Default)]
45pub struct JsonBytesValueCodec<T> {
46    /// Associates the codec with `T` without retaining a value.
47    _marker: PhantomData<T>,
48}
49
50impl<T> JsonBytesValueCodec<T> {
51    /// Creates a bidirectional JSON bytes codec for values of type `T`.
52    ///
53    /// # Returns
54    ///
55    /// Returns a stateless codec bound to values of type `T`.
56    #[inline]
57    pub const fn new() -> Self {
58        Self { _marker: PhantomData }
59    }
60}
61
62impl<T> ValueEncoder<T> for JsonBytesValueCodec<T>
63where
64    T: Serialize,
65{
66    /// Serialization failure reported by Serde JSON.
67    type Error = JsonError;
68    /// Newly allocated UTF-8 JSON bytes owned by the caller.
69    type Output = Vec<u8>;
70
71    /// Serializes `input` into UTF-8 JSON bytes.
72    ///
73    /// # Parameters
74    ///
75    /// - `input`: Value borrowed for the duration of serialization.
76    ///
77    /// # Returns
78    ///
79    /// Returns a newly allocated vector containing the serialized JSON.
80    ///
81    /// # Errors
82    ///
83    /// Returns a JSON error if `T` rejects serialization or contains a map key
84    /// that cannot be represented as a JSON object key.
85    #[inline]
86    fn encode(&mut self, input: &T) -> Result<Self::Output, Self::Error> {
87        JsonBytesValueEncoder::<T>::new().encode(input)
88    }
89}
90
91impl<T> ValueDecoder<[u8]> for JsonBytesValueCodec<T>
92where
93    T: DeserializeOwned,
94{
95    /// JSON syntax, UTF-8, or target-value deserialization failure.
96    type Error = JsonError;
97    /// Owned value deserialized independently of the input byte slice.
98    type Output = T;
99
100    /// Deserializes `input` from UTF-8 JSON bytes.
101    ///
102    /// # Parameters
103    ///
104    /// - `input`: One complete UTF-8 JSON value, optionally surrounded by
105    ///   whitespace.
106    ///
107    /// # Returns
108    ///
109    /// Returns an owned `T`; decoding may allocate according to the target
110    /// type.
111    ///
112    /// # Errors
113    ///
114    /// Returns a JSON error for invalid UTF-8, malformed or incomplete input,
115    /// trailing non-whitespace data, or a value incompatible with `T`.
116    #[inline]
117    fn decode(&mut self, input: &[u8]) -> Result<Self::Output, Self::Error> {
118        JsonBytesValueDecoder::<T>::new().decode(input)
119    }
120}