1use crate::enums::IDeterminantProvider;
18use crate::result::OkGuard;
19use crate::{unreachable_unchecked, IStable};
20
21#[crate::stabby]
23#[derive(Clone, PartialEq, Eq, Hash)]
24pub struct Option<T: IStable + IDeterminantProvider<()>> {
25 inner: crate::result::Result<T, ()>,
26}
27impl<T: IStable> core::fmt::Debug for Option<T>
28where
29 T: IDeterminantProvider<()>,
30 T: core::fmt::Debug,
31{
32 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33 self.as_ref().fmt(f)
34 }
35}
36impl<T: IStable> From<core::option::Option<T>> for Option<T>
37where
38 T: IDeterminantProvider<()>,
39{
40 fn from(value: core::option::Option<T>) -> Self {
41 match value {
42 Some(value) => Self {
43 inner: crate::result::Result::Ok(value),
44 },
45 None => Self {
46 inner: crate::result::Result::Err(()),
47 },
48 }
49 }
50}
51impl<T: IStable> From<Option<T>> for core::option::Option<T>
52where
53 T: IDeterminantProvider<()>,
54{
55 fn from(value: Option<T>) -> Self {
56 value.inner.ok()
57 }
58}
59impl<T: IStable> Default for Option<T>
60where
61 T: IDeterminantProvider<()>,
62{
63 fn default() -> Self {
64 Self::None()
65 }
66}
67pub type SomeGuard<'a, T> = OkGuard<'a, T, ()>;
72impl<T: IStable> Option<T>
73where
74 T: IDeterminantProvider<()>,
75{
76 #[allow(non_snake_case)]
78 pub fn Some(value: T) -> Self {
79 Self {
80 inner: crate::result::Result::Ok(value),
81 }
82 }
83 #[allow(non_snake_case)]
85 pub fn None() -> Self {
86 Self {
87 inner: crate::result::Result::Err(()),
88 }
89 }
90 pub fn as_ref(&self) -> core::option::Option<&T> {
92 self.match_ref(Some, || None)
93 }
94 pub fn as_mut(&mut self) -> core::option::Option<SomeGuard<T>> {
96 self.match_mut(Some, || None)
97 }
98 pub fn match_ref<'a, U, FnSome: FnOnce(&'a T) -> U, FnNone: FnOnce() -> U>(
101 &'a self,
102 some: FnSome,
103 none: FnNone,
104 ) -> U {
105 self.inner.match_ref(some, |_| none())
106 }
107 pub fn match_ref_ctx<'a, I, U, FnSome: FnOnce(I, &'a T) -> U, FnNone: FnOnce(I) -> U>(
109 &'a self,
110 ctx: I,
111 some: FnSome,
112 none: FnNone,
113 ) -> U {
114 self.inner.match_ref_ctx(ctx, some, move |ctx, _| none(ctx))
115 }
116 pub fn match_mut<'a, U, FnSome: FnOnce(SomeGuard<'a, T>) -> U, FnNone: FnOnce() -> U>(
119 &'a mut self,
120 some: FnSome,
121 none: FnNone,
122 ) -> U {
123 self.inner.match_mut(some, |_| none())
124 }
125 pub fn match_mut_ctx<
127 'a,
128 I,
129 U,
130 FnSome: FnOnce(I, SomeGuard<'a, T>) -> U,
131 FnNone: FnOnce(I) -> U,
132 >(
133 &'a mut self,
134 ctx: I,
135 some: FnSome,
136 none: FnNone,
137 ) -> U {
138 self.inner.match_mut_ctx(ctx, some, move |ctx, _| none(ctx))
139 }
140 pub fn match_owned<U, FnSome: FnOnce(T) -> U, FnNone: FnOnce() -> U>(
143 self,
144 some: FnSome,
145 none: FnNone,
146 ) -> U {
147 self.inner.match_owned(some, |_| none())
148 }
149 pub fn match_owned_ctx<I, U, FnSome: FnOnce(I, T) -> U, FnNone: FnOnce(I) -> U>(
151 self,
152 ctx: I,
153 some: FnSome,
154 none: FnNone,
155 ) -> U {
156 self.inner
157 .match_owned_ctx(ctx, some, move |ctx, _| none(ctx))
158 }
159 pub fn is_some(&self) -> bool {
161 self.inner.is_ok()
162 }
163 pub fn is_none(&self) -> bool {
165 !self.is_some()
166 }
167 pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
169 self.match_owned(|x| x, f)
170 }
171 pub unsafe fn unwrap_unchecked(self) -> T {
174 self.unwrap_or_else(|| unsafe { unreachable_unchecked!() })
176 }
177 pub fn unwrap(self) -> T {
180 self.unwrap_or_else(|| panic!("Option::unwrap called on None"))
181 }
182}
183
184#[cfg(feature = "serde")]
185mod serde_impl {
186 use super::*;
187 use serde::{Deserialize, Serialize};
188 impl<Ok: Serialize> Serialize for Option<Ok>
189 where
190 Ok: IDeterminantProvider<()>,
191 {
192 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
193 where
194 S: serde::Serializer,
195 {
196 let this = self.as_ref();
197 this.serialize(serializer)
198 }
199 }
200 impl<'a, Ok: IDeterminantProvider<()>> Deserialize<'a> for Option<Ok>
201 where
202 core::option::Option<Ok>: Deserialize<'a>,
203 {
204 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
205 where
206 D: serde::Deserializer<'a>,
207 {
208 Ok(core::option::Option::<Ok>::deserialize(deserializer)?.into())
209 }
210 }
211}