summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2025-12-08 20:13:20 -0500
committerMica White <botahamec@outlook.com>2025-12-08 20:13:20 -0500
commit6b1f814ea733699f28d9c60202ab8645cdd1c058 (patch)
tree002b1c479ff079c7303a8b13302865b4344f4cae /src/lib.rs
First commitHEADmain
Diffstat (limited to 'src/lib.rs')
-rwxr-xr-xsrc/lib.rs244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100755
index 0000000..08bc0b7
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,244 @@
+#![no_std]
+
+extern crate alloc;
+
+use alloc::boxed::Box;
+use alloc::rc::Rc;
+use alloc::sync::Arc;
+use core::cmp;
+use core::fmt::{self, Debug, Display, Pointer};
+use core::hash::{Hash, Hasher};
+use core::ops::{Deref, DerefMut};
+
+#[derive(Clone, Copy)]
+#[repr(transparent)]
+pub struct SuperPin<Ptr> {
+ pointer: Ptr,
+}
+
+#[macro_export]
+macro_rules! superpin {
+ ($value: expr $(,)?) => {
+ $crate::SuperPin<&mut _> { pointer: &mut { $value } }
+ };
+}
+
+impl<Ptr: Debug> Debug for SuperPin<Ptr> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Debug::fmt(&self.pointer, f)
+ }
+}
+
+impl<Ptr: Display> Display for SuperPin<Ptr> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(&self.pointer, f)
+ }
+}
+
+impl<Ptr: Pointer> Pointer for SuperPin<Ptr> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Pointer::fmt(&self.pointer, f)
+ }
+}
+
+impl<Ptr: Deref, Q: Deref> PartialEq<SuperPin<Q>> for SuperPin<Ptr>
+where
+ Ptr::Target: PartialEq<Q::Target>,
+{
+ fn eq(&self, other: &SuperPin<Q>) -> bool {
+ Ptr::Target::eq(self, other)
+ }
+
+ #[allow(clippy::partialeq_ne_impl)] // We need to copy what the Ptr type does
+ fn ne(&self, other: &SuperPin<Q>) -> bool {
+ Ptr::Target::ne(self, other)
+ }
+}
+
+impl<Ptr: Deref<Target: Eq>> Eq for SuperPin<Ptr> {}
+
+impl<Ptr: Deref, Q: Deref> PartialOrd<SuperPin<Q>> for SuperPin<Ptr>
+where
+ Ptr::Target: PartialOrd<Q::Target>,
+{
+ fn partial_cmp(&self, other: &SuperPin<Q>) -> Option<cmp::Ordering> {
+ Ptr::Target::partial_cmp(self, other)
+ }
+
+ fn lt(&self, other: &SuperPin<Q>) -> bool {
+ Ptr::Target::lt(self, other)
+ }
+
+ fn le(&self, other: &SuperPin<Q>) -> bool {
+ Ptr::Target::le(self, other)
+ }
+
+ fn gt(&self, other: &SuperPin<Q>) -> bool {
+ Ptr::Target::gt(self, other)
+ }
+
+ fn ge(&self, other: &SuperPin<Q>) -> bool {
+ Ptr::Target::ge(self, other)
+ }
+}
+
+impl<Ptr: Deref<Target: Ord>> Ord for SuperPin<Ptr> {
+ fn cmp(&self, other: &Self) -> cmp::Ordering {
+ Ptr::Target::cmp(self, other)
+ }
+}
+
+impl<Ptr: Deref> Hash for SuperPin<Ptr>
+where
+ <Ptr as Deref>::Target: Hash,
+{
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.pointer.hash(state);
+ }
+}
+
+impl<Ptr: Deref> Deref for SuperPin<Ptr> {
+ type Target = Ptr::Target;
+
+ fn deref(&self) -> &Self::Target {
+ &self.pointer
+ }
+}
+
+impl<Ptr: DerefMut> DerefMut for SuperPin<Ptr> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.pointer
+ }
+}
+
+impl<T: ?Sized> From<Box<T>> for SuperPin<Box<T>> {
+ fn from(value: Box<T>) -> Self {
+ // safety: It's not possible to move or replace the insides of a
+ // SuperPin<Box<T>>, so it's safe to pin it directly without
+ // any additional requirements.
+ unsafe { Self::new_unchecked(value) }
+ }
+}
+
+impl<Ptr> SuperPin<Ptr> {
+ pub fn boxed<T>(x: T) -> SuperPin<Box<T>> {
+ SuperPin::from(Box::new(x))
+ }
+
+ pub fn rc<T>(value: T) -> SuperPin<Rc<T>> {
+ // safety: It's not possible to move anything behind an Rc
+ unsafe { SuperPin::new_unchecked(Rc::new(value)) }
+ }
+
+ pub fn arc<T>(value: T) -> SuperPin<Arc<T>> {
+ // safety: It's not possible to move anything behind an Arc
+ unsafe { SuperPin::new_unchecked(Arc::new(value)) }
+ }
+}
+
+impl<Ptr: Deref> SuperPin<Ptr> {
+ pub unsafe fn new_unchecked(pointer: Ptr) -> Self {
+ Self { pointer }
+ }
+
+ pub fn as_ref(&self) -> SuperPin<&<Ptr as Deref>::Target> {
+ // safety: the pointee cannot move while it is pinned
+ unsafe { SuperPin::new_unchecked(self.pointer.deref()) }
+ }
+
+ pub unsafe fn into_inner_unchecked(pin: SuperPin<Ptr>) -> Ptr {
+ // safety: the caller must ensure that the value is not moved
+ pin.pointer
+ }
+}
+
+impl<Ptr: DerefMut> SuperPin<Ptr> {
+ pub fn as_mut(&mut self) -> SuperPin<&mut <Ptr as Deref>::Target> {
+ // safety: the pointee cannot move while it is pinned
+ unsafe { SuperPin::new_unchecked(self.pointer.deref_mut()) }
+ }
+
+ pub fn set(&mut self, value: <Ptr as Deref>::Target)
+ where
+ <Ptr as Deref>::Target: Sized,
+ {
+ // safety: the destructor is run and a new valid value of the same type is
+ // put in its place, so no pinning invariant is violated
+ *self.pointer.deref_mut() = value;
+ }
+}
+
+impl<'a, T: ?Sized> SuperPin<&'a T> {
+ pub unsafe fn map_unchecked<U: ?Sized>(self, func: impl FnOnce(&T) -> &U) -> SuperPin<&'a U> {
+ let new_pointer = func(self.pointer);
+
+ // safety: the caller is responsible for upholding the invariants of
+ // SuperPin::new_unchecked
+ unsafe { SuperPin::new_unchecked(new_pointer) }
+ }
+
+ pub fn get_ref(self) -> &'a T {
+ // safety: it is impossible to move out of a shared pointer
+ self.pointer
+ }
+}
+
+impl<'a, T: ?Sized> SuperPin<&'a mut T> {
+ pub fn into_ref(self) -> SuperPin<&'a T> {
+ // safety: it is impossible to move out of a shared pointer
+ unsafe { SuperPin::new_unchecked(&*self.pointer) }
+ }
+
+ pub unsafe fn get_unchecked_mut(self) -> &'a mut T {
+ // safety: the caller must ensure the value is not moved out of the pointer
+ self.pointer
+ }
+
+ pub unsafe fn map_unchecked_mut<U: ?Sized>(
+ self,
+ func: impl FnOnce(&mut T) -> &mut U,
+ ) -> SuperPin<&'a mut U> {
+ let pointer = &mut *self.pointer;
+ let new_pointer = func(pointer);
+
+ // safety: the caller must uphold the invariants of SuperPin::new_unchecked
+ unsafe { SuperPin::new_unchecked(new_pointer) }
+ }
+}
+
+impl<T: ?Sized> SuperPin<&'static T> {
+ pub fn static_ref(r: &'static T) -> Self {
+ // safety: T is borrowed for the 'static lifetime, which never ends
+ unsafe { SuperPin::new_unchecked(r) }
+ }
+}
+
+impl<T: ?Sized> SuperPin<&'static mut T> {
+ pub fn static_mut(r: &'static mut T) -> Self {
+ // safety: T is borrowed for the 'static lifetime, which never ends
+ unsafe { SuperPin::new_unchecked(r) }
+ }
+}
+
+impl<'a, T> SuperPin<&'a Option<T>> {
+ pub fn as_option_ref(self) -> Option<SuperPin<&'a T>> {
+ unsafe {
+ SuperPin::get_ref(self)
+ .as_ref()
+ // safety: x has to be pinned, because it comes from self
+ .map(|x| SuperPin::new_unchecked(x))
+ }
+ }
+}
+
+impl<'a, T> SuperPin<&'a mut Option<T>> {
+ pub fn as_option_mut(self) -> Option<SuperPin<&'a mut T>> {
+ unsafe {
+ // safety: the value is never moved
+ SuperPin::get_unchecked_mut(self)
+ .as_mut()
+ // safety: x has to be pinned, because it comes from self
+ .map(|x| SuperPin::new_unchecked(x))
+ }
+ }
+}