zvariant/utils.rs
1use std::slice::SliceIndex;
2
3use crate::{Error, Result};
4
5/// The prefix of ARRAY type signature, as a character. Provided for manual signature creation.
6pub const ARRAY_SIGNATURE_CHAR: char = 'a';
7/// The prefix of ARRAY type signature, as a string. Provided for manual signature creation.
8pub const ARRAY_SIGNATURE_STR: &str = "a";
9pub(crate) const ARRAY_ALIGNMENT_DBUS: usize = 4;
10/// The opening character of STRUCT type signature. Provided for manual signature creation.
11pub const STRUCT_SIG_START_CHAR: char = '(';
12/// The closing character of STRUCT type signature. Provided for manual signature creation.
13pub const STRUCT_SIG_END_CHAR: char = ')';
14/// The opening character of STRUCT type signature, as a string. Provided for manual signature
15/// creation.
16pub const STRUCT_SIG_START_STR: &str = "(";
17/// The closing character of STRUCT type signature, as a string. Provided for manual signature
18/// creation.
19pub const STRUCT_SIG_END_STR: &str = ")";
20pub(crate) const STRUCT_ALIGNMENT_DBUS: usize = 8;
21/// The opening character of DICT_ENTRY type signature. Provided for manual signature creation.
22pub const DICT_ENTRY_SIG_START_CHAR: char = '{';
23/// The closing character of DICT_ENTRY type signature. Provided for manual signature creation.
24pub const DICT_ENTRY_SIG_END_CHAR: char = '}';
25/// The opening character of DICT_ENTRY type signature, as a string. Provided for manual signature
26/// creation.
27pub const DICT_ENTRY_SIG_START_STR: &str = "{";
28/// The closing character of DICT_ENTRY type signature, as a string. Provided for manual signature
29/// creation.
30pub const DICT_ENTRY_SIG_END_STR: &str = "}";
31pub(crate) const DICT_ENTRY_ALIGNMENT_DBUS: usize = 8;
32/// The VARIANT type signature. Provided for manual signature creation.
33pub const VARIANT_SIGNATURE_CHAR: char = 'v';
34/// The VARIANT type signature, as a string. Provided for manual signature creation.
35pub const VARIANT_SIGNATURE_STR: &str = "v";
36#[cfg(feature = "gvariant")]
37pub(crate) const VARIANT_ALIGNMENT_GVARIANT: usize = 8;
38/// The prefix of MAYBE (GVariant-specific) type signature, as a character. Provided for manual
39/// signature creation.
40#[cfg(feature = "gvariant")]
41pub const MAYBE_SIGNATURE_CHAR: char = 'm';
42/// The prefix of MAYBE (GVariant-specific) type signature, as a string. Provided for manual
43/// signature creation.
44#[cfg(feature = "gvariant")]
45pub const MAYBE_SIGNATURE_STR: &str = "m";
46
47/// Calculates the padding needed to align `value` to the next multiple of `align`.
48///
49/// # Parameters
50/// - `value`: The value to align.
51/// - `align`: The alignment boundary. Must be a positive power of two.
52///
53/// # Panics
54/// Panics if `align` is not a positive power of two.
55// Public only for tests.
56#[doc(hidden)]
57pub fn padding_for_n_bytes(value: usize, align: usize) -> usize {
58 assert!(
59 align > 0 && align.is_power_of_two(),
60 "`align` must be a positive power of two"
61 );
62 let len_rounded_up = value.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
63
64 len_rounded_up.wrapping_sub(value)
65}
66
67pub(crate) fn usize_to_u32(value: usize) -> u32 {
68 assert!(value <= (u32::MAX as usize), "{value} too large for `u32`",);
69
70 value as u32
71}
72
73pub(crate) fn usize_to_u8(value: usize) -> u8 {
74 assert!(value <= (u8::MAX as usize), "{value} too large for `u8`",);
75
76 value as u8
77}
78
79/// Slice the given slice of bytes safely and return an error if the slice is too small.
80pub(crate) fn subslice<I, T>(input: &[T], index: I) -> Result<&I::Output>
81where
82 I: SliceIndex<[T]>,
83{
84 input.get(index).ok_or(Error::OutOfBounds)
85}