any_null/
lib.rs

1
2#![warn(missing_docs)]
3#![doc = include_str!("../README.md")]
4
5use std::ptr::{self, NonNull};
6use std::rc::{Rc, Weak as WeakRc};
7use std::sync::{Arc, Weak as WeakArc};
8
9/**
10 * Any type that can be some form of null.
11 */
12pub trait Nullable {
13  
14  /**
15   * Whatever value of Self means null.
16   * 
17   * For `*const _`, this is `std::ptr::null()`.
18   * 
19   * For `*mut _`, this is `std::ptr::null_mut()`.
20   * 
21   * See also [`NoneIsNull`]
22   */
23  const NULL: Self;
24  
25  /**
26   * Just a null check without relying on [`PartialEq`] (i.e., `ptr == null()`).
27   * 
28   * For `*const _` and `*mut _`, this uses the inherent method of the same name.
29   */
30  fn is_null(&self) -> bool;
31  
32}
33
34/**
35 *  Conveniently wraps arounnd [`<P as Nullable>::NULL`](Nullable::NULL).
36 */
37pub const fn null<P: Nullable>() -> P {
38  P::NULL
39}
40
41/**
42 * Wraps around [`<P as Nullable>::is_null(ptr)`](Nullable::is_null)
43 */
44pub fn is_null<P: Nullable>(ptr: &P) -> bool {
45  ptr.is_null()
46}
47
48impl<T> Nullable for *const T {
49  
50  const NULL: Self = ptr::null();
51  
52  fn is_null(&self) -> bool {
53    <*const T>::is_null(*self)
54  }
55  
56}
57
58impl<T> Nullable for *mut T {
59  
60  const NULL: Self = ptr::null_mut();
61  
62  fn is_null(&self) -> bool {
63    <*mut T>::is_null(*self)
64  }
65  
66}
67
68impl<T: NoneIsNull> Nullable for Option<T> {
69  
70  const NULL: Self = None;
71  
72  fn is_null(&self) -> bool {
73    self.is_none()
74  }
75  
76}
77
78/**
79 * Many types are not themselves nullable,
80 * but when wrapped in an [`Option`] effectively use [`None`] as null
81 * (especially with the niche-filling optimization).
82 * 
83 * This includes references, [`NonNull`], and most smart pointers
84 * (including all of the smart pointers in [`std`]).
85 */
86pub trait NoneIsNull: Sized {}
87
88impl<T: ?Sized> NoneIsNull for NonNull<T> {}
89
90impl<T: ?Sized> NoneIsNull for Box<T> {}
91
92impl<T: ?Sized> NoneIsNull for Rc<T> {}
93
94impl<T: ?Sized> NoneIsNull for WeakRc<T> {}
95
96impl<T: ?Sized> NoneIsNull for Arc<T> {}
97
98impl<T: ?Sized> NoneIsNull for WeakArc<T> {}
99
100impl<'a, T: ?Sized> NoneIsNull for &'a T {}
101
102impl<'a, T: ?Sized> NoneIsNull for &'a mut T {}