1#![forbid(unsafe_code)]
37#![warn(missing_docs)]
38
39pub mod cid;
41pub mod drisl;
42pub mod errors;
43pub mod value;
44
45pub mod car;
47pub mod storage;
48pub mod varint;
49
50pub mod bdasl;
52pub mod masl;
53pub mod rasl;
54pub mod tiles;
55
56pub use cid::{
58 Cid, CidCore, DAG_CBOR_CODEC, DaslCid, MULTIBASE_IDENTITY, RawCid, compute_cid_blake3,
59 compute_cid_for, compute_raw_cid, compute_raw_cid_blake3, verify_cid_bytes, verify_cid_reader,
60};
61pub use drisl::{
62 DecodeConfig, EncodeConfig, TimeMode, from_reader, from_reader_non_strict,
63 from_reader_with_config, from_slice, from_slice_non_strict, from_slice_with_config, to_vec,
64 to_vec_with_config, to_writer, to_writer_with_config,
65};
66pub use errors::{
67 CarError, DaslCidError, DecodeError, EncodeError, MaslError, RaslError, StorageError,
68 TilesError, VarintError,
69};
70pub use value::Ipld;
71
72pub use car::{CarBlock, CarConfig, CarHeader, CarReader, CarWriter, LimitsConfig};
74pub use storage::{BlockStorage, DiskStorage, MemoryStorage, SpillableBuffer, SpillableReader};
75
76#[cfg(feature = "reqwest")]
78pub use rasl::fetch::{fetch_verified, fetch_verified_with_client};
79
80#[cfg(feature = "axum")]
81pub use rasl::handler::{directory_handler, func_handler, redirect_handler};
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use serde::{Deserialize, Serialize};
87
88 #[test]
89 fn test_roundtrip_primitives() {
90 let bytes = to_vec(&true).unwrap();
92 assert_eq!(from_slice::<bool>(&bytes).unwrap(), true);
93
94 let bytes = to_vec(&42i32).unwrap();
96 assert_eq!(from_slice::<i32>(&bytes).unwrap(), 42);
97
98 let bytes = to_vec(&"hello").unwrap();
100 assert_eq!(from_slice::<String>(&bytes).unwrap(), "hello");
101
102 let none: Option<i32> = None;
104 let bytes = to_vec(&none).unwrap();
105 assert_eq!(from_slice::<Option<i32>>(&bytes).unwrap(), None);
106 }
107
108 #[test]
109 fn test_roundtrip_struct() {
110 #[derive(Serialize, Deserialize, Debug, PartialEq)]
111 struct Test {
112 a: i32,
113 b: String,
114 }
115
116 let original = Test {
117 a: 42,
118 b: "hello".to_string(),
119 };
120 let bytes = to_vec(&original).unwrap();
121 let decoded: Test = from_slice(&bytes).unwrap();
122 assert_eq!(original, decoded);
123 }
124
125 #[test]
126 fn test_roundtrip_nested() {
127 #[derive(Serialize, Deserialize, Debug, PartialEq)]
128 struct Inner {
129 value: i32,
130 }
131
132 #[derive(Serialize, Deserialize, Debug, PartialEq)]
133 struct Outer {
134 inner: Inner,
135 list: Vec<i32>,
136 }
137
138 let original = Outer {
139 inner: Inner { value: 42 },
140 list: vec![1, 2, 3],
141 };
142 let bytes = to_vec(&original).unwrap();
143 let decoded: Outer = from_slice(&bytes).unwrap();
144 assert_eq!(original, decoded);
145 }
146
147 #[test]
148 fn test_map_key_sorting() {
149 use std::collections::BTreeMap;
150
151 let mut map = BTreeMap::new();
152 map.insert("z".to_string(), 1);
153 map.insert("a".to_string(), 2);
154 map.insert("m".to_string(), 3);
155
156 let bytes = to_vec(&map).unwrap();
157
158 assert_eq!(
159 bytes,
160 vec![0xa3, 0x61, 0x61, 0x02, 0x61, 0x6d, 0x03, 0x61, 0x7a, 0x01]
161 );
162 }
163
164 #[test]
165 fn test_strict_rejects_non_canonical() {
166 let bytes = [0x18, 0x00];
167 assert!(from_slice::<u8>(&bytes).is_err());
168 assert_eq!(from_slice_non_strict::<u8>(&bytes).unwrap(), 0);
169 }
170
171 #[test]
172 fn test_float_rejects_nan() {
173 let result = to_vec(&f64::NAN);
174 assert!(result.is_err());
175 }
176
177 #[test]
178 fn test_float_rejects_infinity() {
179 let result = to_vec(&f64::INFINITY);
180 assert!(result.is_err());
181
182 let result = to_vec(&f64::NEG_INFINITY);
183 assert!(result.is_err());
184 }
185}