Implement full SSD1306 OLED display support: - Splash screen on boot (1.5s) with project name, version, board - Dashboard showing radio state, config, counters, RSSI/SNR - RSSI history sparkline (64-sample ring buffer, 2px-wide bars) - DisplayOn/DisplayOff host commands routed via dedicated channel - Pure render functions against generic DrawTarget (no hardware coupling) - Display on/off control bypasses radio task entirely Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
306 lines
9.7 KiB
Rust
306 lines
9.7 KiB
Rust
/// Everything in this module is internal API and may change at any time.
|
|
#[doc(hidden)]
|
|
pub mod __internal {
|
|
/// A reexport of core to allow our macros to be generic to std vs core.
|
|
pub use ::core as core_export;
|
|
|
|
/// A reexport of serde so our users don't have to also have a serde dependency.
|
|
#[cfg(feature = "serde")]
|
|
pub use serde;
|
|
|
|
/// Reexports of internal types
|
|
pub use crate::{
|
|
repr::{ArrayRepr, EnumSetTypeRepr},
|
|
traits::{EnumSetConstHelper, EnumSetTypePrivate},
|
|
};
|
|
|
|
#[cfg(feature = "serde")]
|
|
#[doc(hidden)]
|
|
#[macro_export]
|
|
macro_rules! __if_serde {
|
|
($($tt:tt)*) => {
|
|
$($tt)*
|
|
};
|
|
}
|
|
|
|
#[cfg(not(feature = "serde"))]
|
|
#[doc(hidden)]
|
|
#[macro_export]
|
|
macro_rules! __if_serde {
|
|
($($tt:tt)*) => {};
|
|
}
|
|
|
|
/// Macro to wrap serde-related code generated by the derive, discarding it
|
|
/// if serde support is not enabled.
|
|
pub use __if_serde;
|
|
|
|
pub use crate::macros::set;
|
|
}
|
|
|
|
/// Helper functions for sets.
|
|
pub mod set {
|
|
use crate::__internal::EnumSetConstHelper;
|
|
use crate::{EnumSet, EnumSetType};
|
|
|
|
/// Retrieves the helper used in constant time operations.
|
|
#[inline(always)]
|
|
pub const fn op_helper<T: EnumSetConstHelper>(_: &T) -> T::ConstOpHelper {
|
|
T::CONST_OP_HELPER
|
|
}
|
|
|
|
/// Retrieves the helper used in constant time conversions.
|
|
#[inline(always)]
|
|
pub const fn init_helper<T: EnumSetConstHelper>(_: &T) -> T::ConstInitHelper {
|
|
T::CONST_INIT_HELPER
|
|
}
|
|
|
|
/// Gets the underlying repr from an EnumSet
|
|
#[inline(always)]
|
|
pub const fn get<T: EnumSetType>(set: EnumSet<T>) -> T::Repr {
|
|
set.repr
|
|
}
|
|
|
|
/// Constructs an EnumSet from the underlying repr
|
|
#[inline(always)]
|
|
pub const fn new<T: EnumSetType>(set: T::Repr) -> EnumSet<T> {
|
|
EnumSet { repr: set }
|
|
}
|
|
}
|
|
|
|
/// Creates a EnumSet literal, which can be used in const contexts.
|
|
///
|
|
/// The syntax used is `enum_set!(Type::A | Type::B | Type::C)`. Each variant must be of the same
|
|
/// type, or an error will occur at compile-time.
|
|
///
|
|
/// This macro accepts trailing `|`s to allow easier use in other macros.
|
|
///
|
|
/// # Performance
|
|
///
|
|
/// This macro is designed for use in const contexts, not for execution as normal code. It may be
|
|
/// significantly slower than normal code outside const contexts.
|
|
///
|
|
/// In normal code, directly use `Type::A | Type::B | Type::C` instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// # use enumset::*;
|
|
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C }
|
|
/// const CONST_SET: EnumSet<Enum> = enum_set!(Enum::A | Enum::B);
|
|
/// assert_eq!(CONST_SET, Enum::A | Enum::B);
|
|
/// ```
|
|
///
|
|
/// This macro is strongly typed. For example, the following will not compile:
|
|
///
|
|
/// ```compile_fail
|
|
/// # use enumset::*;
|
|
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C }
|
|
/// # #[derive(EnumSetType, Debug)] enum Enum2 { A, B, C }
|
|
/// let type_error = enum_set!(Enum::A | Enum2::B);
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! enum_set {
|
|
($(|)*) => {
|
|
$crate::EnumSet::empty()
|
|
};
|
|
($value:path $(|)*) => {
|
|
{
|
|
$crate::__internal::set::init_helper(&$value).const_only($value)
|
|
}
|
|
};
|
|
($value:path | $($rest:path)|* $(|)*) => {
|
|
$crate::enum_set_union!($value, $($rest,)*)
|
|
};
|
|
}
|
|
|
|
/// Computes the union of multiple enums or constants enumset at compile time.
|
|
///
|
|
/// The syntax used is `enum_set_union!(ENUM_A, ENUM_B, ENUM_C)`, computing the equivalent of
|
|
/// `ENUM_A | ENUM_B | ENUM_C` at compile time. Each variant must be of the same type, or an error
|
|
/// will occur at compile-time.
|
|
///
|
|
/// # Performance
|
|
///
|
|
/// This macro is designed for use in const contexts, not for execution as normal code. It may be
|
|
/// significantly slower than normal code outside const contexts.
|
|
///
|
|
/// In normal code, directly use the `|` operator instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// # use enumset::*;
|
|
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C }
|
|
/// const CONST_SET: EnumSet<Enum> = enum_set_union!(Enum::A, Enum::B);
|
|
/// assert_eq!(CONST_SET, Enum::A | Enum::B);
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! enum_set_union {
|
|
($value:path $(,)?) => {
|
|
$crate::enum_set!($value)
|
|
};
|
|
($value:path, $($rest:path),* $(,)?) => {
|
|
{
|
|
let op_helper = $crate::__internal::set::op_helper(&$value);
|
|
let value = $crate::enum_set!($value);
|
|
$(let value = {
|
|
let new = $crate::enum_set!($rest);
|
|
op_helper.const_union(value, new)
|
|
};)*
|
|
value
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Computes the intersection of multiple enums or constants enumset at compile time.
|
|
///
|
|
/// The syntax used is `enum_set_intersection!(ENUM_A, ENUM_B, ENUM_C)`, computing the equivalent
|
|
/// of `ENUM_A & ENUM_B & ENUM_C` at compile time. Each variant must be of the same type, or an
|
|
/// error will occur at compile-time.
|
|
///
|
|
/// # Performance
|
|
///
|
|
/// This macro is designed for use in const contexts, not for execution as normal code. It may be
|
|
/// significantly slower than normal code outside const contexts.
|
|
///
|
|
/// In normal code, directly use the `&` operator instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// # use enumset::*;
|
|
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C, D }
|
|
/// const SET_A: EnumSet<Enum> = enum_set!(Enum::A | Enum::B);
|
|
/// const SET_B: EnumSet<Enum> = enum_set!(Enum::B | Enum::C);
|
|
/// const CONST_SET: EnumSet<Enum> = enum_set_intersection!(SET_A, SET_B);
|
|
/// assert_eq!(CONST_SET, Enum::B);
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! enum_set_intersection {
|
|
($value:path $(,)?) => {
|
|
$crate::enum_set!($value)
|
|
};
|
|
($value:path, $($rest:path),* $(,)?) => {
|
|
{
|
|
let op_helper = $crate::__internal::set::op_helper(&$value);
|
|
let value = $crate::enum_set!($value);
|
|
$(let value = {
|
|
let new = $crate::enum_set!($rest);
|
|
op_helper.const_intersection(value, new)
|
|
};)*
|
|
value
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Computes the complement of an enums or constants enumset at compile time.
|
|
///
|
|
/// # Performance
|
|
///
|
|
/// This macro is designed for use in const contexts, not for execution as normal code. It may be
|
|
/// significantly slower than normal code outside const contexts.
|
|
///
|
|
/// In normal code, directly use the `!` operator instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// # use enumset::*;
|
|
/// #[derive(EnumSetType, Debug)]
|
|
/// enum Enum { A, B, C, D }
|
|
///
|
|
/// const SET: EnumSet<Enum> = enum_set!(Enum::B | Enum::C);
|
|
/// const CONST_SET: EnumSet<Enum> = enum_set_complement!(SET);
|
|
/// assert_eq!(CONST_SET, Enum::A | Enum::D);
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! enum_set_complement {
|
|
($value:path $(,)?) => {{
|
|
let op_helper = $crate::__internal::set::op_helper(&$value);
|
|
let value = $crate::enum_set!($value);
|
|
op_helper.const_complement(value)
|
|
}};
|
|
}
|
|
|
|
/// Computes the difference of multiple enums or constants enumset at compile time.
|
|
///
|
|
/// The syntax used is `enum_set_difference!(ENUM_A, ENUM_B, ENUM_C)`, computing the equivalent
|
|
/// of `ENUM_A - ENUM_B - ENUM_C` at compile time. Each variant must be of the same type, or an
|
|
/// error will occur at compile-time.
|
|
///
|
|
/// # Performance
|
|
///
|
|
/// This macro is designed for use in const contexts, not for execution as normal code. It may be
|
|
/// significantly slower than normal code outside const contexts.
|
|
///
|
|
/// In normal code, directly use the `-` operator instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// # use enumset::*;
|
|
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C, D }
|
|
/// const SET_A: EnumSet<Enum> = enum_set!(Enum::A | Enum::B | Enum::D);
|
|
/// const SET_B: EnumSet<Enum> = enum_set!(Enum::B | Enum::C);
|
|
/// const CONST_SET: EnumSet<Enum> = enum_set_symmetric_difference!(SET_A, SET_B);
|
|
/// assert_eq!(CONST_SET, Enum::A | Enum::C | Enum::D);
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! enum_set_difference {
|
|
($value:path $(,)?) => {
|
|
$crate::enum_set!($value)
|
|
};
|
|
($value:path, $($rest:path),* $(,)?) => {
|
|
{
|
|
let op_helper = $crate::__internal::set::op_helper(&$value);
|
|
let value = $crate::enum_set!($value);
|
|
$(let value = {
|
|
let new = $crate::enum_set!($rest);
|
|
op_helper.const_intersection(value, op_helper.const_complement(new))
|
|
};)*
|
|
value
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Computes the symmetric difference of multiple enums or constants enumset at compile time.
|
|
///
|
|
/// The syntax used is `enum_set_symmetric_difference!(ENUM_A, ENUM_B, ENUM_C)`, computing the
|
|
/// equivalent of `ENUM_A ^ ENUM_B ^ ENUM_C` at compile time. Each variant must be of the same
|
|
/// type, or an error will occur at compile-time.
|
|
///
|
|
/// # Performance
|
|
///
|
|
/// This macro is designed for use in const contexts, not for execution as normal code. It may be
|
|
/// significantly slower than normal code outside const contexts.
|
|
///
|
|
/// In normal code, directly use the `^` operator instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// # use enumset::*;
|
|
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C, D }
|
|
/// const SET_A: EnumSet<Enum> = EnumSet::all();
|
|
/// const SET_B: EnumSet<Enum> = enum_set!(Enum::B | Enum::C);
|
|
/// const CONST_SET: EnumSet<Enum> = enum_set_difference!(SET_A, SET_B);
|
|
/// assert_eq!(CONST_SET, Enum::A | Enum::D);
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! enum_set_symmetric_difference {
|
|
($value:path $(,)?) => {
|
|
$crate::enum_set!($value)
|
|
};
|
|
($value:path, $($rest:path),* $(,)?) => {
|
|
{
|
|
let op_helper = $crate::__internal::set::op_helper(&$value);
|
|
let value = $crate::enum_set!($value);
|
|
$(let value = {
|
|
let new = $crate::enum_set!($rest);
|
|
op_helper.const_symmetric_difference(value, new)
|
|
};)*
|
|
value
|
|
}
|
|
};
|
|
}
|