embeddenator_interop/
lib.rs1pub mod adapters;
47pub mod ffi;
48pub mod formats;
49pub mod kernel_interop;
50
51#[cfg(feature = "python")]
52pub mod bindings;
53
54pub use kernel_interop::*;
56
57pub use formats::{FormatError, OutputFormat};
59
60pub use adapters::{AutoFormatAdapter, BatchAdapter, EnvelopeAdapter, FileAdapter, StreamAdapter};
62
63pub fn export_to_json(vec: &embeddenator_vsa::SparseVec) -> Result<String, FormatError> {
65 let bytes = formats::sparse_vec_to_format(vec, OutputFormat::Json)?;
66 String::from_utf8(bytes).map_err(|e| FormatError::SerializationFailed(e.to_string()))
67}
68
69pub fn import_from_json(json: &str) -> Result<embeddenator_vsa::SparseVec, FormatError> {
70 formats::sparse_vec_from_format(json.as_bytes(), OutputFormat::Json)
71}
72
73pub struct VSAHandle {
75 vec: embeddenator_vsa::SparseVec,
76}
77
78impl VSAHandle {
79 pub fn from_sparse_vec(vec: embeddenator_vsa::SparseVec) -> Self {
80 Self { vec }
81 }
82
83 pub fn to_sparse_vec(&self) -> embeddenator_vsa::SparseVec {
84 self.vec.clone()
85 }
86
87 pub fn dimensions(&self) -> (usize, usize) {
88 let nnz = self.vec.pos.len() + self.vec.neg.len();
89 (embeddenator_vsa::DIM, nnz)
90 }
91}
92
93#[cfg(test)]
94mod integration_tests {
95 use super::*;
96 use adapters::BatchAdapter;
97 use embeddenator_vsa::{ReversibleVSAConfig, SparseVec};
98 use formats::{sparse_vec_from_format, sparse_vec_to_format};
99
100 #[test]
101 fn test_format_roundtrip() {
102 let vec = SparseVec {
103 pos: vec![1, 2, 3],
104 neg: vec![4, 5],
105 };
106
107 let json = sparse_vec_to_format(&vec, OutputFormat::Json).unwrap();
109 let from_json = sparse_vec_from_format(&json, OutputFormat::Json).unwrap();
110 assert_eq!(vec.pos, from_json.pos);
111
112 let bincode = sparse_vec_to_format(&vec, OutputFormat::Bincode).unwrap();
114 let from_bincode = sparse_vec_from_format(&bincode, OutputFormat::Bincode).unwrap();
115 assert_eq!(vec.pos, from_bincode.pos);
116 }
117
118 #[test]
119 fn test_batch_operations() {
120 let config = ReversibleVSAConfig::default();
121 let data = vec![b"test1".as_slice(), b"test2".as_slice()];
122
123 let vectors = BatchAdapter::batch_encode(&data, &config);
124 assert_eq!(vectors.len(), 2);
125
126 let decoded = BatchAdapter::batch_decode(&vectors, &config, 5);
127 assert_eq!(decoded.len(), 2);
128 }
129
130 #[test]
131 fn test_kernel_backend() {
132 let backend = SparseVecBackend;
133 let config = ReversibleVSAConfig::default();
134
135 let data = b"test data";
136 let vec = backend.encode_data(data, &config, None);
137 let decoded = backend.decode_data(&vec, &config, None, data.len());
138
139 assert_eq!(data.len(), decoded.len());
141
142 let vec2 = backend.encode_data(b"other", &config, None);
144 let _bundled = backend.bundle(&vec, &vec2);
145 let _bound = backend.bind(&vec, &vec2);
146 let similarity = backend.cosine(&vec, &vec2);
147
148 assert!((0.0..=1.0).contains(&similarity));
149 }
150}