ab_io_type/
fixed_capacity_string.rs1#[cfg(test)]
2mod tests;
3
4use crate::alignment::Alignment;
5use crate::fixed_capacity_elements::{FixedCapacityElements, SUPPORTED_CAPACITY};
6use crate::metadata::{IoTypeMetadataKind, MAX_METADATA_CAPACITY, concat_metadata_sources};
7use crate::trivial_type::TrivialType;
8use crate::unaligned::Unaligned;
9use core::ops::{Deref, DerefMut};
10
11#[derive(Debug, Copy, Clone)]
21#[repr(C)]
22pub struct FixedCapacityString<const CAPACITY: usize> {
23 bytes: FixedCapacityElements<u8, CAPACITY>,
24}
25
26impl<const CAPACITY: usize> Default for FixedCapacityString<CAPACITY>
27where
28 [(); SUPPORTED_CAPACITY::<u8, CAPACITY>]:,
29{
30 #[inline(always)]
31 fn default() -> Self {
32 Self {
33 bytes: FixedCapacityElements::default(),
34 }
35 }
36}
37
38impl<const CAPACITY: usize> Deref for FixedCapacityString<CAPACITY> {
39 type Target = FixedCapacityElements<u8, CAPACITY>;
40
41 fn deref(&self) -> &Self::Target {
42 &self.bytes
43 }
44}
45
46impl<const CAPACITY: usize> DerefMut for FixedCapacityString<CAPACITY> {
47 fn deref_mut(&mut self) -> &mut Self::Target {
48 &mut self.bytes
49 }
50}
51
52unsafe impl<const CAPACITY: usize> TrivialType for FixedCapacityString<CAPACITY>
55where
56 [(); SUPPORTED_CAPACITY::<u8, CAPACITY>]:,
57{
58 const ALIGNMENT: Alignment = FixedCapacityElements::<u8, CAPACITY>::ALIGNMENT;
59 const METADATA: &[u8] = {
61 #[inline(always)]
62 const fn metadata(capacity: u32) -> ([u8; MAX_METADATA_CAPACITY], usize) {
63 concat_metadata_sources(&[
64 &[IoTypeMetadataKind::FixedCapacityString as u8],
65 &capacity.to_le_bytes(),
66 ])
67 }
68
69 let (metadata_scratch, metadata_size) = &metadata(CAPACITY as u32);
71 metadata_scratch.split_at(*metadata_size).0
72 };
73
74 #[inline(always)]
75 fn try_from_bytes_unaligned(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
76 let (_value, remainder) =
77 FixedCapacityElements::<u8, CAPACITY>::try_from_bytes_unaligned(bytes)?;
78 let value = unsafe { bytes.as_ptr().cast::<Unaligned<Self>>().as_ref_unchecked() };
81 Some((value, remainder))
82 }
83}
84
85impl<const CAPACITY: usize> FixedCapacityString<CAPACITY>
86where
87 [(); SUPPORTED_CAPACITY::<u8, CAPACITY>]:,
88{
89 #[inline(always)]
93 pub fn try_from_str(s: &str) -> Option<Self> {
94 Self::try_from_slice(s.as_bytes())
95 }
96
97 #[inline(always)]
101 pub fn try_from_slice(bytes: &[u8]) -> Option<Self> {
102 Some(Self {
103 bytes: FixedCapacityElements::try_from_slice(bytes)?,
104 })
105 }
106}