Skip to main content

xdr_common/
cfg.rs

1// Copied from https://github.com/stellar/xdrgen/blob/master/lib/xdrgen/generators/rust/src/types.rs
2
3#![allow(unused_imports)]
4#![allow(dead_code)]
5
6#[cfg(all(feature = "serde", feature = "alloc"))]
7pub(crate) use serde::de::{
8    Deserialize, Deserializer, Error as DeError, IgnoredAny, SeqAccess, Visitor,
9};
10#[cfg(all(feature = "serde", feature = "alloc"))]
11pub(crate) use serde::ser::{Error as SerError, Serialize, Serializer};
12
13#[cfg(feature = "alloc")]
14pub(crate) use alloc::{
15    borrow::ToOwned,
16    string::{FromUtf8Error, String},
17};
18
19/// A pointer type that uniquely owns a heap allocation of type `T`.
20///
21/// # Feature Variants
22///
23/// - **With `alloc` feature**: Standard heap-allocated `Box<T>` from the alloc crate
24/// - **Without `alloc` feature**: Transparent newtype holding `T` inline
25#[cfg_attr(docsrs, doc(cfg(all())))]
26#[cfg(feature = "alloc")]
27pub type Box<T> = alloc::boxed::Box<T>;
28
29/// No-`alloc` stand-in for `Box<T>`: a transparent newtype holding `T`
30/// inline.
31///
32/// Without an allocator nothing can be heap-boxed, and a `&'static T` cannot
33/// be decoded into from a non-`'static` buffer, so a boxed field would make
34/// the derived `ReadXDR<'r>` of its containing type fail to compile. Holding
35/// the value inline keeps encoding, decoding and size bounds working, and
36/// keeping `Box<T>` a distinct type from `T` keeps `Box::new`, `Deref`,
37/// `AsRef<T>` and impl coherence identical to the `alloc` `Box`.
38/// Recursive types still need `alloc`: through an inline `Box` they have
39/// infinite size.
40#[cfg_attr(docsrs, doc(hidden))]
41#[cfg(not(feature = "alloc"))]
42#[derive(Clone, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
43#[repr(transparent)]
44pub struct Box<T>(T);
45
46#[cfg(not(feature = "alloc"))]
47impl<T> Box<T> {
48    /// Wraps `x` (inline; nothing is allocated).
49    #[inline]
50    pub const fn new(x: T) -> Self {
51        Self(x)
52    }
53    /// Unwraps the value.
54    #[inline]
55    pub fn into_inner(b: Self) -> T {
56        b.0
57    }
58}
59
60#[cfg(not(feature = "alloc"))]
61impl<T> core::ops::Deref for Box<T> {
62    type Target = T;
63    #[inline]
64    fn deref(&self) -> &T {
65        &self.0
66    }
67}
68#[cfg(not(feature = "alloc"))]
69impl<T> core::ops::DerefMut for Box<T> {
70    #[inline]
71    fn deref_mut(&mut self) -> &mut T {
72        &mut self.0
73    }
74}
75#[cfg(not(feature = "alloc"))]
76impl<T> AsRef<T> for Box<T> {
77    #[inline]
78    fn as_ref(&self) -> &T {
79        &self.0
80    }
81}
82#[cfg(not(feature = "alloc"))]
83impl<T> AsMut<T> for Box<T> {
84    #[inline]
85    fn as_mut(&mut self) -> &mut T {
86        &mut self.0
87    }
88}
89#[cfg(not(feature = "alloc"))]
90impl<T> core::borrow::Borrow<T> for Box<T> {
91    #[inline]
92    fn borrow(&self) -> &T {
93        &self.0
94    }
95}
96#[cfg(not(feature = "alloc"))]
97impl<T> From<T> for Box<T> {
98    #[inline]
99    fn from(x: T) -> Self {
100        Self(x)
101    }
102}
103#[cfg(not(feature = "alloc"))]
104impl<T: core::fmt::Debug> core::fmt::Debug for Box<T> {
105    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
106        self.0.fmt(f)
107    }
108}
109#[cfg(not(feature = "alloc"))]
110impl<T: core::fmt::Display> core::fmt::Display for Box<T> {
111    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
112        self.0.fmt(f)
113    }
114}
115
116/// Borrows the value behind a [`Box`] in a `const` context.
117///
118/// `const fn` code cannot go through `Deref`, so the `ConstWriteXDR` derive
119/// uses this to reach a boxed field. With `alloc` it is the heap `Box`'s
120/// (const) deref; without `alloc` it borrows the inline value.
121#[cfg(feature = "alloc")]
122#[inline]
123pub const fn box_as_ref<T>(b: &Box<T>) -> &T {
124    b
125}
126
127/// Borrows the value behind a [`Box`] in a `const` context.
128///
129/// `const fn` code cannot go through `Deref`, so the `ConstWriteXDR` derive
130/// uses this to reach a boxed field. With `alloc` it is the heap `Box`'s
131/// (const) deref; without `alloc` it borrows the inline value.
132#[cfg(not(feature = "alloc"))]
133#[inline]
134pub const fn box_as_ref<T>(b: &Box<T>) -> &T {
135    &b.0
136}
137
138/// A contiguous growable array type.
139///
140/// # Feature Variants
141///
142/// - **With `alloc` feature**: Standard heap-allocated `Vec<T>` from the alloc crate
143/// - **Without `alloc` feature**: Type alias for `&'static [T]`, requires static data
144#[cfg_attr(docsrs, doc(cfg(all())))]
145#[cfg(feature = "alloc")]
146pub type Vec<T> = alloc::vec::Vec<T>;
147
148/// No-`alloc` stand-in for `Vec<T>`: an alias for `&'static [T]`,
149/// requiring static data.
150#[cfg_attr(docsrs, doc(hidden))]
151#[cfg(not(feature = "alloc"))]
152pub type Vec<T> = &'static [T];