triblespace_core/blob/encodings/
array.rs1use core::marker::PhantomData;
10
11use anybytes::view::ViewError;
12use anybytes::{Bytes, View};
13use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
14
15use crate::blob::{Blob, BlobEncoding, TryFromBlob};
16use crate::macros::entity;
17use crate::metadata;
18use crate::metadata::MetaDescribe;
19use crate::trible::Fragment;
20
21pub trait ArrayElement: MetaDescribe + 'static {
28 type Native: IntoBytes + Immutable + TryFromBytes + KnownLayout + Sync + Send + 'static;
30}
31
32pub struct Array<T: ArrayElement>(PhantomData<T>);
41
42impl<T: ArrayElement> BlobEncoding for Array<T> {}
43
44impl<T: ArrayElement> MetaDescribe for Array<T> {
45 fn describe() -> Fragment {
46 let mut core = entity! {
55 metadata::array_item_schema*: T::describe(),
56 metadata::tag: metadata::KIND_BLOB_ENCODING,
57 };
58 let id = core.root().expect("rooted");
59 let id_ref = crate::id::ExclusiveId::force_ref(&id);
60 core += entity! { id_ref @
61 metadata::name: "array",
62 metadata::description:
63 "Flat array of typed values in native byte order. \
64 Shape is stored externally in TribleSpace triples.",
65 };
66 core
67 }
68}
69
70impl<T: ArrayElement> crate::inline::Encodes<Vec<T::Native>> for Array<T>
72where
73 crate::inline::encodings::hash::Handle<Array<T>>: crate::inline::InlineEncoding,
74{
75 type Output = Blob<Array<T>>;
76 fn encode(source: Vec<T::Native>) -> Blob<Array<T>> {
77 Blob::new(Bytes::from_source(source))
78 }
79}
80
81impl<T: ArrayElement> TryFromBlob<Array<T>> for Bytes {
83 type Error = core::convert::Infallible;
84 fn try_from_blob(blob: Blob<Array<T>>) -> Result<Self, Self::Error> {
85 Ok(blob.bytes)
86 }
87}
88
89pub mod elements {
93 use super::ArrayElement;
94 use crate::macros::entity;
95 use crate::metadata::{self, MetaDescribe};
96 use crate::trible::Fragment;
97
98 macro_rules! impl_array_element {
99 ($marker:ident, $native:ty, $id:expr, $doc:expr) => {
100 #[doc = $doc]
101 pub struct $marker;
102
103 impl MetaDescribe for $marker {
104 fn describe() -> Fragment {
105 let id = crate::id_hex!($id);
113 entity! { crate::id::ExclusiveId::force_ref(&id) @
114 metadata::name: stringify!($marker),
115 metadata::description: $doc,
116 }
117 }
118 }
119
120 impl ArrayElement for $marker {
121 type Native = $native;
122 }
123 };
124 }
125
126 impl_array_element!(
127 F32,
128 f32,
129 "92F4DB8D84519C8D6E212CB810FF40D4",
130 "32-bit IEEE-754 float."
131 );
132 impl_array_element!(
133 F64,
134 f64,
135 "FA3AD8DEC844D5F409AB728269B7A3FE",
136 "64-bit IEEE-754 float."
137 );
138 impl_array_element!(
139 U8,
140 u8,
141 "D16AC7C02F25E4799F4D47EB1E51EF6E",
142 "Unsigned 8-bit integer."
143 );
144 impl_array_element!(
145 U16,
146 u16,
147 "C14453D98F283B96A1010A9F24D53B17",
148 "Unsigned 16-bit integer."
149 );
150 impl_array_element!(
151 U32,
152 u32,
153 "1B9DD214A02C58D9141EF802273120F8",
154 "Unsigned 32-bit integer."
155 );
156 impl_array_element!(
157 U64,
158 u64,
159 "323C0143534D3AD4898D69EA5597414A",
160 "Unsigned 64-bit integer."
161 );
162 impl_array_element!(
163 I8,
164 i8,
165 "E68060AF27227583CB1AEDF89E17E278",
166 "Signed 8-bit integer."
167 );
168 impl_array_element!(
169 I16,
170 i16,
171 "E72199687209A576562B5BD7196FD755",
172 "Signed 16-bit integer."
173 );
174 impl_array_element!(
175 I32,
176 i32,
177 "AB831A6CCDAF7F49BA5BEADEA32CA04E",
178 "Signed 32-bit integer."
179 );
180 impl_array_element!(
181 I64,
182 i64,
183 "53426475A3C695420B23C329285DCA57",
184 "Signed 64-bit integer."
185 );
186}
187
188impl<T: ArrayElement> TryFromBlob<Array<T>> for View<[T::Native]> {
194 type Error = ViewError;
195 fn try_from_blob(blob: Blob<Array<T>>) -> Result<Self, Self::Error> {
196 blob.bytes.view()
197 }
198}