1use std::cmp::Ordering;
2use std::convert::TryInto;
3use std::fmt::Debug;
4use std::mem::size_of;
5#[cfg(feature = "chrono_v0_4")]
6mod chrono_v0_4;
7#[cfg(feature = "uuid")]
8mod uuid;
9
10#[derive(Eq, PartialEq, Clone, Debug)]
11enum TypeClassification {
12 Internal,
13 UserDefined,
14 Internal2,
17}
18
19impl TypeClassification {
20 fn to_byte(&self) -> u8 {
21 match self {
22 TypeClassification::Internal => 1,
23 TypeClassification::UserDefined => 2,
24 TypeClassification::Internal2 => 3,
25 }
26 }
27
28 fn from_byte(value: u8) -> Self {
29 match value {
30 1 => TypeClassification::Internal,
31 2 => TypeClassification::UserDefined,
32 3 => TypeClassification::Internal2,
33 _ => unreachable!(),
34 }
35 }
36}
37
38#[derive(Eq, PartialEq, Debug, Clone)]
39pub struct TypeName {
40 classification: TypeClassification,
41 name: String,
42}
43
44impl TypeName {
45 pub fn new(name: &str) -> Self {
48 Self {
49 classification: TypeClassification::UserDefined,
50 name: name.to_string(),
51 }
52 }
53
54 pub(crate) fn internal(name: &str) -> Self {
55 Self {
56 classification: TypeClassification::Internal,
57 name: name.to_string(),
58 }
59 }
60
61 pub(crate) fn internal2(name: &str) -> Self {
62 Self {
63 classification: TypeClassification::Internal2,
64 name: name.to_string(),
65 }
66 }
67
68 pub(crate) fn to_bytes(&self) -> Vec<u8> {
69 let mut result = Vec::with_capacity(self.name.len() + 1);
70 result.push(self.classification.to_byte());
71 result.extend_from_slice(self.name.as_bytes());
72 result
73 }
74
75 pub(crate) fn from_bytes(bytes: &[u8]) -> Self {
76 let classification = TypeClassification::from_byte(bytes[0]);
77 let name = std::str::from_utf8(&bytes[1..]).unwrap().to_string();
78
79 Self {
80 classification,
81 name,
82 }
83 }
84
85 pub fn name(&self) -> &str {
86 &self.name
87 }
88}
89
90pub trait Value: Debug {
92 type SelfType<'a>: Debug + 'a
94 where
95 Self: 'a;
96
97 type AsBytes<'a>: AsRef<[u8]> + 'a
98 where
99 Self: 'a;
100
101 fn fixed_width() -> Option<usize>;
103
104 fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a>
107 where
108 Self: 'a;
109
110 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a>
112 where
113 Self: 'b;
114
115 fn type_name() -> TypeName;
117}
118
119pub trait MutInPlaceValue: Value {
122 type BaseRefType: Debug + ?Sized;
124
125 fn initialize(data: &mut [u8]);
128
129 fn from_bytes_mut(data: &mut [u8]) -> &mut Self::BaseRefType;
130}
131
132impl MutInPlaceValue for &[u8] {
133 type BaseRefType = [u8];
134
135 fn initialize(_data: &mut [u8]) {
136 }
138
139 fn from_bytes_mut(data: &mut [u8]) -> &mut Self::BaseRefType {
140 data
141 }
142}
143
144pub trait Key: Value {
146 fn compare(data1: &[u8], data2: &[u8]) -> Ordering;
148}
149
150impl Value for () {
151 type SelfType<'a>
152 = ()
153 where
154 Self: 'a;
155 type AsBytes<'a>
156 = &'a [u8]
157 where
158 Self: 'a;
159
160 fn fixed_width() -> Option<usize> {
161 Some(0)
162 }
163
164 #[allow(clippy::unused_unit, clippy::semicolon_if_nothing_returned)]
165 fn from_bytes<'a>(_data: &'a [u8]) -> ()
166 where
167 Self: 'a,
168 {
169 ()
170 }
171
172 #[allow(clippy::ignored_unit_patterns)]
173 fn as_bytes<'a, 'b: 'a>(_: &'a Self::SelfType<'b>) -> &'a [u8]
174 where
175 Self: 'b,
176 {
177 &[]
178 }
179
180 fn type_name() -> TypeName {
181 TypeName::internal("()")
182 }
183}
184
185impl Key for () {
186 fn compare(_data1: &[u8], _data2: &[u8]) -> Ordering {
187 Ordering::Equal
188 }
189}
190
191impl Value for bool {
192 type SelfType<'a>
193 = bool
194 where
195 Self: 'a;
196 type AsBytes<'a>
197 = &'a [u8]
198 where
199 Self: 'a;
200
201 fn fixed_width() -> Option<usize> {
202 Some(1)
203 }
204
205 fn from_bytes<'a>(data: &'a [u8]) -> bool
206 where
207 Self: 'a,
208 {
209 match data[0] {
210 0 => false,
211 1 => true,
212 _ => unreachable!(),
213 }
214 }
215
216 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> &'a [u8]
217 where
218 Self: 'b,
219 {
220 match value {
221 true => &[1],
222 false => &[0],
223 }
224 }
225
226 fn type_name() -> TypeName {
227 TypeName::internal("bool")
228 }
229}
230
231impl Key for bool {
232 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
233 let value1 = Self::from_bytes(data1);
234 let value2 = Self::from_bytes(data2);
235 value1.cmp(&value2)
236 }
237}
238
239impl<T: Value> Value for Option<T> {
240 type SelfType<'a>
241 = Option<T::SelfType<'a>>
242 where
243 Self: 'a;
244 type AsBytes<'a>
245 = Vec<u8>
246 where
247 Self: 'a;
248
249 fn fixed_width() -> Option<usize> {
250 T::fixed_width().map(|x| x + 1)
251 }
252
253 fn from_bytes<'a>(data: &'a [u8]) -> Option<T::SelfType<'a>>
254 where
255 Self: 'a,
256 {
257 match data[0] {
258 0 => None,
259 1 => Some(T::from_bytes(&data[1..])),
260 _ => unreachable!(),
261 }
262 }
263
264 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Vec<u8>
265 where
266 Self: 'b,
267 {
268 let mut result = vec![0];
269 if let Some(x) = value {
270 result[0] = 1;
271 result.extend_from_slice(T::as_bytes(x).as_ref());
272 } else if let Some(fixed_width) = T::fixed_width() {
273 result.extend_from_slice(&vec![0; fixed_width]);
274 }
275 result
276 }
277
278 fn type_name() -> TypeName {
279 TypeName::internal(&format!("Option<{}>", T::type_name().name()))
280 }
281}
282
283impl<T: Key> Key for Option<T> {
284 #[allow(clippy::collapsible_else_if)]
285 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
286 if data1[0] == 0 {
287 if data2[0] == 0 {
288 Ordering::Equal
289 } else {
290 Ordering::Less
291 }
292 } else {
293 if data2[0] == 0 {
294 Ordering::Greater
295 } else {
296 T::compare(&data1[1..], &data2[1..])
297 }
298 }
299 }
300}
301
302impl Value for &[u8] {
303 type SelfType<'a>
304 = &'a [u8]
305 where
306 Self: 'a;
307 type AsBytes<'a>
308 = &'a [u8]
309 where
310 Self: 'a;
311
312 fn fixed_width() -> Option<usize> {
313 None
314 }
315
316 fn from_bytes<'a>(data: &'a [u8]) -> &'a [u8]
317 where
318 Self: 'a,
319 {
320 data
321 }
322
323 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> &'a [u8]
324 where
325 Self: 'b,
326 {
327 value
328 }
329
330 fn type_name() -> TypeName {
331 TypeName::internal("&[u8]")
332 }
333}
334
335impl Key for &[u8] {
336 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
337 data1.cmp(data2)
338 }
339}
340
341impl<const N: usize> Value for &[u8; N] {
342 type SelfType<'a>
343 = &'a [u8; N]
344 where
345 Self: 'a;
346 type AsBytes<'a>
347 = &'a [u8; N]
348 where
349 Self: 'a;
350
351 fn fixed_width() -> Option<usize> {
352 Some(N)
353 }
354
355 fn from_bytes<'a>(data: &'a [u8]) -> &'a [u8; N]
356 where
357 Self: 'a,
358 {
359 data.try_into().unwrap()
360 }
361
362 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> &'a [u8; N]
363 where
364 Self: 'b,
365 {
366 value
367 }
368
369 fn type_name() -> TypeName {
370 TypeName::internal(&format!("[u8;{N}]"))
371 }
372}
373
374impl<const N: usize> Key for &[u8; N] {
375 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
376 data1.cmp(data2)
377 }
378}
379
380impl<const N: usize, T: Value> Value for [T; N] {
381 type SelfType<'a>
382 = [T::SelfType<'a>; N]
383 where
384 Self: 'a;
385 type AsBytes<'a>
386 = Vec<u8>
387 where
388 Self: 'a;
389
390 fn fixed_width() -> Option<usize> {
391 T::fixed_width().map(|x| x * N)
392 }
393
394 fn from_bytes<'a>(data: &'a [u8]) -> [T::SelfType<'a>; N]
395 where
396 Self: 'a,
397 {
398 let mut result = Vec::with_capacity(N);
399 if let Some(fixed) = T::fixed_width() {
400 for i in 0..N {
401 result.push(T::from_bytes(&data[fixed * i..fixed * (i + 1)]));
402 }
403 } else {
404 let mut start = size_of::<u32>() * N;
406 for i in 0..N {
407 let range = size_of::<u32>() * i..size_of::<u32>() * (i + 1);
408 let end = u32::from_le_bytes(data[range].try_into().unwrap()) as usize;
409 result.push(T::from_bytes(&data[start..end]));
410 start = end;
411 }
412 }
413 result.try_into().unwrap()
414 }
415
416 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Vec<u8>
417 where
418 Self: 'b,
419 {
420 if let Some(fixed) = T::fixed_width() {
421 let mut result = Vec::with_capacity(fixed * N);
422 for item in value {
423 result.extend_from_slice(T::as_bytes(item).as_ref());
424 }
425 result
426 } else {
427 let mut result = vec![0u8; size_of::<u32>() * N];
429 for i in 0..N {
430 result.extend_from_slice(T::as_bytes(&value[i]).as_ref());
431 let end: u32 = result.len().try_into().unwrap();
432 result[size_of::<u32>() * i..size_of::<u32>() * (i + 1)]
433 .copy_from_slice(&end.to_le_bytes());
434 }
435 result
436 }
437 }
438
439 fn type_name() -> TypeName {
440 TypeName::internal(&format!("[{};{N}]", T::type_name().name()))
443 }
444}
445
446impl<const N: usize, T: Key> Key for [T; N] {
447 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
448 if let Some(fixed) = T::fixed_width() {
449 for i in 0..N {
450 let range = fixed * i..fixed * (i + 1);
451 let comparison = T::compare(&data1[range.clone()], &data2[range]);
452 if !comparison.is_eq() {
453 return comparison;
454 }
455 }
456 } else {
457 let mut start1 = size_of::<u32>() * N;
459 let mut start2 = size_of::<u32>() * N;
460 for i in 0..N {
461 let range = size_of::<u32>() * i..size_of::<u32>() * (i + 1);
462 let end1 = u32::from_le_bytes(data1[range.clone()].try_into().unwrap()) as usize;
463 let end2 = u32::from_le_bytes(data2[range].try_into().unwrap()) as usize;
464 let comparison = T::compare(&data1[start1..end1], &data2[start2..end2]);
465 if !comparison.is_eq() {
466 return comparison;
467 }
468 start1 = end1;
469 start2 = end2;
470 }
471 }
472 Ordering::Equal
473 }
474}
475
476impl Value for &str {
477 type SelfType<'a>
478 = &'a str
479 where
480 Self: 'a;
481 type AsBytes<'a>
482 = &'a str
483 where
484 Self: 'a;
485
486 fn fixed_width() -> Option<usize> {
487 None
488 }
489
490 fn from_bytes<'a>(data: &'a [u8]) -> &'a str
491 where
492 Self: 'a,
493 {
494 std::str::from_utf8(data).unwrap()
495 }
496
497 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> &'a str
498 where
499 Self: 'b,
500 {
501 value
502 }
503
504 fn type_name() -> TypeName {
505 TypeName::internal("&str")
506 }
507}
508
509impl Key for &str {
510 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
511 let str1 = Self::from_bytes(data1);
512 let str2 = Self::from_bytes(data2);
513 str1.cmp(str2)
514 }
515}
516
517impl Value for String {
518 type SelfType<'a>
519 = String
520 where
521 Self: 'a;
522 type AsBytes<'a>
523 = &'a str
524 where
525 Self: 'a;
526
527 fn fixed_width() -> Option<usize> {
528 None
529 }
530
531 fn from_bytes<'a>(data: &'a [u8]) -> String
532 where
533 Self: 'a,
534 {
535 std::str::from_utf8(data).unwrap().to_string()
536 }
537
538 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> &'a str
539 where
540 Self: 'b,
541 {
542 value.as_str()
543 }
544
545 fn type_name() -> TypeName {
546 TypeName::internal("String")
547 }
548}
549
550impl Key for String {
551 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
552 let str1 = std::str::from_utf8(data1).unwrap();
553 let str2 = std::str::from_utf8(data2).unwrap();
554 str1.cmp(str2)
555 }
556}
557
558impl Value for char {
559 type SelfType<'a> = char;
560 type AsBytes<'a>
561 = [u8; 3]
562 where
563 Self: 'a;
564
565 fn fixed_width() -> Option<usize> {
566 Some(3)
567 }
568
569 fn from_bytes<'a>(data: &'a [u8]) -> char
570 where
571 Self: 'a,
572 {
573 char::from_u32(u32::from_le_bytes([data[0], data[1], data[2], 0])).unwrap()
574 }
575
576 fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> [u8; 3]
577 where
578 Self: 'b,
579 {
580 let bytes = u32::from(*value).to_le_bytes();
581 [bytes[0], bytes[1], bytes[2]]
582 }
583
584 fn type_name() -> TypeName {
585 TypeName::internal(stringify!(char))
586 }
587}
588
589impl Key for char {
590 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
591 Self::from_bytes(data1).cmp(&Self::from_bytes(data2))
592 }
593}
594
595macro_rules! le_value {
596 ($t:ty) => {
597 impl Value for $t {
598 type SelfType<'a> = $t;
599 type AsBytes<'a>
600 = [u8; std::mem::size_of::<$t>()]
601 where
602 Self: 'a;
603
604 fn fixed_width() -> Option<usize> {
605 Some(std::mem::size_of::<$t>())
606 }
607
608 fn from_bytes<'a>(data: &'a [u8]) -> $t
609 where
610 Self: 'a,
611 {
612 <$t>::from_le_bytes(data.try_into().unwrap())
613 }
614
615 fn as_bytes<'a, 'b: 'a>(
616 value: &'a Self::SelfType<'b>,
617 ) -> [u8; std::mem::size_of::<$t>()]
618 where
619 Self: 'a,
620 Self: 'b,
621 {
622 value.to_le_bytes()
623 }
624
625 fn type_name() -> TypeName {
626 TypeName::internal(stringify!($t))
627 }
628 }
629 };
630}
631
632macro_rules! le_impl {
633 ($t:ty) => {
634 le_value!($t);
635
636 impl Key for $t {
637 fn compare(data1: &[u8], data2: &[u8]) -> Ordering {
638 Self::from_bytes(data1).cmp(&Self::from_bytes(data2))
639 }
640 }
641 };
642}
643
644le_impl!(u8);
645le_impl!(u16);
646le_impl!(u32);
647le_impl!(u64);
648le_impl!(u128);
649le_impl!(i8);
650le_impl!(i16);
651le_impl!(i32);
652le_impl!(i64);
653le_impl!(i128);
654le_value!(f32);
655le_value!(f64);