justcode_core/lib.rs
1//! # Justcode
2//!
3//! A compact binary encoder/decoder with space-efficient encoding scheme.
4//! The encoded size will be the same or smaller than the in-memory size.
5//!
6//! ## Features
7//!
8//! - Compact binary encoding (space-efficient)
9//! - Varint encoding for lengths and small integers
10//! - Architecture invariant (byte-order independent)
11//! - Streaming Reader/Writer API
12//! - Configurable encoding options
13//!
14//! ## Example
15//!
16//! ```rust
17//! use justcode_core::{Encode, Decode, config};
18//!
19//! #[derive(Encode, Decode, PartialEq, Debug)]
20//! struct Entity {
21//! x: f32,
22//! y: f32,
23//! }
24//!
25//! #[derive(Encode, Decode, PartialEq, Debug)]
26//! struct World(Vec<Entity>);
27//!
28//! fn main() {
29//! let config = config::standard();
30//! let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]);
31//!
32//! let encoded = justcode_core::encode_to_vec(&world, config).unwrap();
33//! let (decoded, len) = justcode_core::decode_from_slice(&encoded, config).unwrap();
34//!
35//! assert_eq!(world, decoded);
36//! assert_eq!(len, encoded.len());
37//! }
38//! ```
39
40#![cfg_attr(not(feature = "std"), no_std)]
41
42#[cfg(not(feature = "std"))]
43extern crate alloc;
44
45#[cfg(not(feature = "std"))]
46use alloc::vec::Vec;
47
48pub mod config;
49pub mod decode;
50pub mod encode;
51pub mod error;
52pub mod reader;
53pub mod varint;
54pub mod writer;
55
56pub use config::Config;
57pub use decode::Decode;
58pub use encode::Encode;
59pub use error::{JustcodeError, Result};
60
61// Re-export derive macros (when derive feature is enabled)
62#[cfg(feature = "derive")]
63pub use justcode_derive::{Decode, Encode};
64
65/// Encode a value to a `Vec<u8>`.
66///
67/// # Example
68///
69/// ```rust
70/// use justcode_core::{Encode, config};
71///
72/// let value = 42u32;
73/// let config = config::standard();
74/// let encoded = justcode_core::encode_to_vec(&value, config).unwrap();
75/// ```
76pub fn encode_to_vec<T: Encode>(value: &T, config: Config) -> Result<Vec<u8>> {
77 let mut writer = writer::Writer::new(config);
78 value.encode(&mut writer)?;
79 Ok(writer.into_bytes())
80}
81
82/// Decode a value from a byte slice.
83///
84/// Returns the decoded value and the number of bytes consumed.
85///
86/// # Example
87///
88/// ```rust
89/// use justcode_core::{Decode, config};
90///
91/// let data = [0x2A, 0x00, 0x00, 0x00];
92/// let config = config::standard();
93/// let (value, len): (u32, usize) = justcode_core::decode_from_slice(&data, config).unwrap();
94/// assert_eq!(value, 42);
95/// assert_eq!(len, 4);
96/// ```
97pub fn decode_from_slice<T: Decode>(bytes: &[u8], config: Config) -> Result<(T, usize)> {
98 let mut reader = reader::Reader::new(bytes, config);
99 let value = T::decode(&mut reader)?;
100 let len = reader.bytes_read();
101 Ok((value, len))
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[test]
109 fn test_encode_decode_u32() {
110 let config = config::standard();
111 let value = 42u32;
112 let encoded = encode_to_vec(&value, config).unwrap();
113 let (decoded, len): (u32, usize) = decode_from_slice(&encoded, config).unwrap();
114 assert_eq!(value, decoded);
115 assert_eq!(len, encoded.len());
116 }
117
118 #[test]
119 fn test_encode_decode_vec() {
120 let config = config::standard();
121 let value = vec![1u32, 2, 3, 4];
122 let encoded = encode_to_vec(&value, config).unwrap();
123 let (decoded, len): (Vec<u32>, usize) = decode_from_slice(&encoded, config).unwrap();
124 assert_eq!(value, decoded);
125 assert_eq!(len, encoded.len());
126 }
127}
128