Skip to main content

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")]
41#[deprecated(
42    since = "5.15.0",
43    note = "GVariant support is deprecated and will be removed in zvariant 6.0. Use the \
44            `zgvariant` crate instead."
45)]
46pub const MAYBE_SIGNATURE_CHAR: char = 'm';
47/// The prefix of MAYBE (GVariant-specific) type signature, as a string. Provided for manual
48/// signature creation.
49#[cfg(feature = "gvariant")]
50#[deprecated(
51    since = "5.15.0",
52    note = "GVariant support is deprecated and will be removed in zvariant 6.0. Use the \
53            `zgvariant` crate instead."
54)]
55pub const MAYBE_SIGNATURE_STR: &str = "m";
56
57/// Calculates the padding needed to align `value` to the next multiple of `align`.
58///
59/// # Parameters
60/// - `value`: The value to align.
61/// - `align`: The alignment boundary. Must be a positive power of two.
62///
63/// # Panics
64/// Panics if `align` is not a positive power of two.
65// Public only for tests.
66#[doc(hidden)]
67pub fn padding_for_n_bytes(value: usize, align: usize) -> usize {
68    assert!(
69        align > 0 && align.is_power_of_two(),
70        "`align` must be a positive power of two"
71    );
72    let len_rounded_up = value.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
73
74    len_rounded_up.wrapping_sub(value)
75}
76
77pub(crate) fn usize_to_u32(value: usize) -> u32 {
78    assert!(value <= (u32::MAX as usize), "{value} too large for `u32`",);
79
80    value as u32
81}
82
83pub(crate) fn usize_to_u8(value: usize) -> u8 {
84    assert!(value <= (u8::MAX as usize), "{value} too large for `u8`",);
85
86    value as u8
87}
88
89/// Slice the given slice of bytes safely and return an error if the slice is too small.
90pub(crate) fn subslice<I, T>(input: &[T], index: I) -> Result<&I::Output>
91where
92    I: SliceIndex<[T]>,
93{
94    input.get(index).ok_or(Error::OutOfBounds)
95}