lace_sans_io/records/
mod.rs1pub(crate) mod blob;
4pub(crate) mod erasure;
5pub(crate) mod file;
6pub(crate) mod hash;
7pub(crate) mod metadata;
8pub(crate) mod plex;
9pub(crate) mod record;
10pub(crate) mod seal;
11pub(crate) mod spec;
12pub(crate) mod typed_text;
13pub(crate) mod util;
14pub(crate) mod validator;
15
16#[cfg(test)]
17mod layout_tests;
18
19pub use b64a::{b64a_decode, b64a_decoded_len, b64a_encode, b64a_encoded_len};
20pub use schnorr_blake3::{CryptoError, Mark, SigningKey, VerificationKey};
21
22pub fn blake3_hash(data: &[u8]) -> [u8; 32] {
24 blake3::hash(data).into()
25}
26
27pub fn random_aux_rand32() -> Result<[u8; 32], getrandom::Error> {
29 loop {
30 let mut aux = zeroize::Zeroizing::new([0; 32]);
31 getrandom::fill(&mut *aux)?;
32 if *aux != [0; 32] {
33 return Ok(*aux);
34 }
35 }
36}
37pub use hash::{HashTextError, RECORD_HASH_B64A_LEN, RECORD_HASH_TEXT_LEN, RecordHash, RecordKind};
38pub use metadata::{ApplicationFieldIter, FieldOccurrence, IndexedField, RecordMetadata};
39pub use record::{Record, RecordReadError};
40pub use validator::{RecordError, RecordValidator, ValidatedHeader};
41
42#[cfg(feature = "internal")]
44#[doc(hidden)]
45pub mod internal {
46 pub fn derive_aux_rand32(input: &[u8]) -> [u8; 32] {
48 blake3::derive_key("lace-🖧/deterministic-aux", input)
49 }
50 pub use super::spec::new_record_with_aux_rand32;
51}
52
53pub use spec::{IntoRecordData, RecordCreateError, RecordSpec, new_record};
54pub use typed_text::{
55 BY_SECRET_TEXT_LEAD, BY_VALUE_TEXT_LEAD, BySecret, ByValue, REGISTERED_TYPED_TEXT_LEADS,
56 TypedH3Text, TypedTextError, generate_by_secret, typed_text_lead_description,
57};
58pub(crate) use util::validate_projected_field_name_value;
59pub use util::{
60 LENGTH_FIELD, MAX_BLOB_RECORD_BYTES, MAX_BLOB_SIZE, MAX_FIELD_LINE_BYTES_EXCLUDING_LF,
61 MAX_H3_RECORD_BYTES, MAX_PLEX_FIELDS, MAX_PLEX_RECORD_BYTES, MAX_RECORD_METADATA_BYTES,
62 RECORD_GLYPH, SYNTHETIC_FIELD_NAMES, TYPE_FIELD, is_synthetic_field_name,
63};
64
65pub trait IntoRecordBatch {
67 fn into_records(self) -> Vec<Record>;
68}
69
70impl IntoRecordBatch for Record {
71 fn into_records(self) -> Vec<Record> {
72 vec![self]
73 }
74}
75impl IntoRecordBatch for &Record {
76 fn into_records(self) -> Vec<Record> {
77 vec![self.clone()]
78 }
79}
80impl IntoRecordBatch for Vec<Record> {
81 fn into_records(self) -> Vec<Record> {
82 self
83 }
84}
85impl IntoRecordBatch for &[Record] {
86 fn into_records(self) -> Vec<Record> {
87 self.to_vec()
88 }
89}
90impl<const N: usize> IntoRecordBatch for [Record; N] {
91 fn into_records(self) -> Vec<Record> {
92 Vec::from(self)
93 }
94}
95
96#[doc(hidden)]
97#[macro_export]
98macro_rules! __lace_record_spec_apply {
99 ($spec:ident $(,)?) => {};
100 ($spec:ident, by_secret: $value:expr $(, $($rest:tt)*)?) => {{
101 $spec = $spec.by_secret($value);
102 $crate::__lace_record_spec_apply!($spec $(, $($rest)*)?);
103 }};
104 ($spec:ident, data: $value:expr $(, $($rest:tt)*)?) => {{
105 $spec = $spec.data($value);
106 $crate::__lace_record_spec_apply!($spec $(, $($rest)*)?);
107 }};
108 ($spec:ident, fields: { $( $name:literal : $value:expr ),* $(,)? } $(, $($rest:tt)*)?) => {{
109 $(
110 $spec = $spec.field($name, $value);
111 )*
112 $crate::__lace_record_spec_apply!($spec $(, $($rest)*)?);
113 }};
114 ($spec:ident, fields: [ $( ( $name:expr, $value:expr ) ),* $(,)? ] $(, $($rest:tt)*)?) => {{
115 $(
116 $spec = $spec.field($name, $value);
117 )*
118 $crate::__lace_record_spec_apply!($spec $(, $($rest)*)?);
119 }};
120 ($spec:ident, fields: $value:expr $(, $($rest:tt)*)?) => {{
121 $spec = $spec.fields($value);
122 $crate::__lace_record_spec_apply!($spec $(, $($rest)*)?);
123 }};
124}
125
126#[macro_export]
128macro_rules! spec {
129 ({ $($body:tt)* }) => {{
130 let mut __lace_record_spec = $crate::records::RecordSpec::new();
131 $crate::__lace_record_spec_apply!(__lace_record_spec, $($body)*);
132 __lace_record_spec
133 }};
134 ($base:expr, { $($body:tt)* }) => {{
135 let mut __lace_record_spec = ($base).clone();
136 $crate::__lace_record_spec_apply!(__lace_record_spec, $($body)*);
137 __lace_record_spec
138 }};
139}
140
141#[macro_export]
143macro_rules! record {
144 ({ $($body:tt)* }) => {{
145 $crate::records::new_record($crate::spec!({ $($body)* }))
146 }};
147 ($base:expr, { $($body:tt)* }) => {{
148 $crate::records::new_record($crate::spec!($base, { $($body)* }))
149 }};
150}