#![doc = r3_core::bind::__internal_module_doc!("r3_core", r#"
<div class="admonition-follows"></div>
> This module re-exports stable items from [`r3_core::bind`][] as well as
> providing some additional items.
"#, concat!(r#"
<div class="toc-header"></div>
"#, r3_core::bind::__internal_module_doc_toc!(), r#"
- [Examples](#examples)
- [Structs](#structs) <!-- this section is generated by rustdoc -->
- [Constants](#constants) <!-- this section is generated by rustdoc -->
- [Traits](#traits) <!-- this section is generated by rustdoc -->
- [Functions](#functions) <!-- this section is generated by rustdoc -->
"#))]
#![doc = crate::tests::doc_test!(
/// ```rust
/// use r3::{
/// kernel::{StaticTask, StaticTimer},
/// bind::{bind, Bind},
/// time::Duration,
/// prelude::*,
/// };
///
/// # type Objects = ();
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
/// C: ~const traits::CfgTask<System = System> +
/// ~const traits::CfgTimer,
/// {
/// // Create a binding and give the timer an exclusive access
/// let count = bind((), || 0).finish(cfg);
/// StaticTimer::define()
/// // `(x,)` is a one-element tuple
/// .start_with_bind((count.borrow_mut(),), |count: &mut i32| {
/// // The counter persists across invocations
/// assert!(*count >= 5);
/// *count += 1;
/// # if *count == 10 { exit(0); }
/// })
/// .period(Duration::from_millis(50))
/// .delay(Duration::ZERO)
/// .active(true)
/// .finish(cfg);
///
/// // Although we gave the timer an exclusive access to `count`,
/// // We can still borrow `count` temporarily before the timer
/// // starts running. (The initialization of bindings happens in
/// // startup hooks, which run before all tasks and timers.)
/// bind(
/// (count.borrow_mut(),),
/// |count: &mut i32| {
/// *count = 5;
/// },
/// ).unpure().finish(cfg);
///
/// // Create a binding
/// let num = bind((), || 42).finish(cfg);
///
/// // Alternatively, without using `bind`:
/// // let num = Bind::define().init(|| 42).finish(cfg);
///
/// // Then create a reference to it, a reference to the reference,
/// // and so on.
/// let num = bind((num.take_mut(),), |x| x).finish(cfg);
/// let num = bind((num.take_mut(),), |x| x).finish(cfg);
/// let num = bind((num.take_mut(),), |x| x).finish(cfg);
///
/// StaticTask::define()
/// .start_with_bind(
/// (num.borrow_mut(),),
/// |num: &mut &'static mut &'static mut &'static mut i32| {
/// assert_eq!(****num, 42);
/// }
/// )
/// .priority(2)
/// .active(true)
/// .finish(cfg);
/// }
/// ```
)]
#![doc = crate::tests::doc_test!(
/// ```rust,compile_fail,E0080
/// # use r3::{
/// # kernel::{StaticTask, StaticTimer},
/// # bind::bind,
/// # time::Duration,
/// # prelude::*,
/// # };
/// # type Objects = ();
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
/// C: ~const traits::CfgTask<System = System> +
/// ~const traits::CfgTimer,
/// {
/// let count = bind((), || 0).finish(cfg);
/// StaticTimer::define()
/// .start_with_bind((count.borrow_mut(),), |count: &mut i32| {})
/// .period(Duration::from_millis(50))
/// .delay(Duration::ZERO)
/// .active(true)
/// .finish(cfg);
///
/// StaticTask::define()
/// // ERROR: `count` is already mutably borrowed by the timer
/// .start_with_bind((count.borrow_mut(),), |count: &mut i32| {})
/// .priority(2)
/// .active(true)
/// .finish(cfg);
/// }
/// ```
)]
#![doc = include_str!("../common.md")]
use r3_core::kernel::cfg;
pub use r3_core::bind::{
fn_bind_map, Bind, BindBorrow, BindBorrowMut, BindDefiner, BindRef, BindTable, BindTake,
BindTakeMut, BindTakeRef, Binder, ExecutableDefiner, ExecutableDefinerExt, FnBind, FnBindMap,
FnBindNever, UnzipBind, INIT_HOOK_PRIORITY,
};
#[inline]
pub const fn bind<System, Binder, Func>(
binder: Binder,
func: Func,
) -> BindDefiner<System, Binder, Func> {
Bind::define().init_with_bind(binder, func)
}
#[doc = crate::tests::doc_test!(
/// ```rust
/// use r3::{
/// kernel::{StaticTask, StaticTimer},
/// bind::{bind, bind_uninit},
/// time::Duration,
/// prelude::*,
/// };
/// use core::mem::MaybeUninit as Mu;
///
/// # type Objects = ();
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
/// C: ~const traits::CfgBase<System = System>,
/// {
/// bind(
/// (bind_uninit(cfg).take_mut(), bind_uninit(cfg).take_mut()),
/// |cell0: &'static mut Mu<_>, cell1: &'static mut Mu<_>| {
/// // Put a value in `cell0` and get a `'static` reference to it
/// let ref0: &'static mut i32 = cell0.write(42);
///
/// // And so on
/// let ref1: &'static mut &'static mut i32 = cell1.write(ref0);
///
/// assert_eq!(ref1, &mut &mut 42);
/// # exit(0);
/// }
/// ).unpure().finish(cfg);
/// }
/// ```
)]
#[inline]
pub const fn bind_uninit<'pool, T, C>(
cfg: &mut cfg::Cfg<'pool, C>,
) -> Bind<'pool, C::System, core::mem::MaybeUninit<T>>
where
T: 'static,
C: ~const cfg::CfgStatic,
{
unsafe { Bind::define().uninit_unchecked().finish(cfg) }
}
#[doc = crate::tests::doc_test!(
/// ```rust
/// use r3::{bind::{bind, bind_default}, prelude::*,};
///
/// # type Objects = ();
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
/// where
/// C: ~const traits::CfgBase<System = System>,
/// {
/// let b = bind_default(cfg);
/// bind((b.borrow(),), |b: &Option<i32>| {
/// assert!(b.is_none());
/// # exit(0);
/// }).unpure().finish(cfg);
/// }
/// ```
)]
#[inline]
pub const fn bind_default<'pool, T, C>(cfg: &mut cfg::Cfg<'pool, C>) -> Bind<'pool, C::System, T>
where
T: Default + 'static,
C: ~const cfg::CfgStatic,
{
Bind::define().init(Default::default).finish(cfg)
}