infinitable/
lib.rs

1//! Infinity for types without infinite values
2//!
3//! Infinitable introduces the notion of "infinity" and "negative infinity"
4//! to numeric types, such as integers, that do not have infinite values.
5//!
6//! A representation of infinity is useful for graph algorithms such as
7//! Dijkstra's algorithm, as well as for representing a graph with an
8//! adjacency matrix.
9//!
10//! # Basic Usage
11//!
12//! ```
13//! use infinitable::*;
14//!
15//! let finite = Finite(5);
16//! let infinity = Infinity;
17//! let negative_infinity = NegativeInfinity;
18//!
19//! assert!(finite < infinity);
20//! assert!(finite > negative_infinity);
21//! ```
22
23#![cfg_attr(not(test), no_std)]
24
25use core::cmp::Ordering;
26use core::fmt;
27use core::fmt::{Display, Formatter};
28use core::ops::{Add, Div, Mul, Neg, Sub};
29use num_traits::Zero;
30
31/// An "infinitable" value, one that can be either finite or infinite
32///
33/// # Versioning
34///
35/// Available since 1.0.0. Variants are re-exported since 1.3.0.
36#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
37pub enum Infinitable<T> {
38    /// A finite value `T`
39    Finite(T),
40    /// Positive infinity, which compares greater than all other values
41    Infinity,
42    /// Negative infinity, which compares less than all other values
43    NegativeInfinity,
44}
45
46pub use Infinitable::{Finite, Infinity, NegativeInfinity};
47
48impl<T> Infinitable<T> {
49    /// Returns `true` if the value is [`Finite`].
50    ///
51    /// # Examples
52    ///
53    /// ```
54    /// use infinitable::*;
55    ///
56    /// let finite = Finite(5);
57    /// assert!(finite.is_finite());
58    /// let infinite: Infinitable<i32> = Infinity;
59    /// assert!(!infinite.is_finite());
60    /// ```
61    ///
62    /// # Versioning
63    ///
64    /// Available since 1.0.0.
65    #[must_use]
66    pub fn is_finite(&self) -> bool {
67        match self {
68            Finite(_) => true,
69            _ => false,
70        }
71    }
72
73    /// Converts from an `Infinitable<T>` to an [`Option<T>`].
74    ///
75    /// Converts `self` into an [`Option<T>`] possibly containing
76    /// a finite value, consuming `self`.
77    ///
78    /// # Examples
79    ///
80    /// ```
81    /// use infinitable::*;
82    ///
83    /// let finite = Finite(5);
84    /// assert_eq!(Some(5), finite.finite());
85    /// let infinite: Infinitable<i32> = Infinity;
86    /// assert_eq!(None, infinite.finite());
87    /// ```
88    ///
89    /// # Versioning
90    ///
91    /// Available since 1.1.0.
92    #[must_use]
93    pub fn finite(self) -> Option<T> {
94        match self {
95            Finite(x) => Some(x),
96            _ => None,
97        }
98    }
99
100    /// Converts from [`Option<T>`] to [`Finite`] or [`Infinity`].
101    ///
102    /// <code>[Some]\(T)</code> is converted to <code>[Finite]\(T)</code>,
103    /// and [`None`] is converted to [`Infinity`].
104    ///
105    /// # Examples
106    ///
107    /// ```
108    /// use infinitable::*;
109    ///
110    /// let finite = Finite(5);
111    /// assert_eq!(finite, Infinitable::finite_or_infinity(Some(5)));
112    /// let infinite: Infinitable<i32> = Infinity;
113    /// assert_eq!(infinite, Infinitable::finite_or_infinity(None));
114    /// ```
115    ///
116    /// # Versioning
117    ///
118    /// Available since 1.3.0.
119    #[must_use]
120    pub fn finite_or_infinity(option: Option<T>) -> Infinitable<T> {
121        match option {
122            Some(x) => Finite(x),
123            None => Infinity,
124        }
125    }
126
127    /// Converts from [`Option<T>`] to [`Finite`] or [`NegativeInfinity`].
128    ///
129    /// <code>[Some]\(T)</code> is converted to <code>[Finite]\(T)</code>,
130    /// and [`None`] is converted to [`NegativeInfinity`].
131    ///
132    /// # Examples
133    ///
134    /// ```
135    /// use infinitable::*;
136    ///
137    /// let finite = Finite(5);
138    /// assert_eq!(finite, Infinitable::finite_or_negative_infinity(Some(5)));
139    /// let infinite: Infinitable<i32> = NegativeInfinity;
140    /// assert_eq!(infinite, Infinitable::finite_or_negative_infinity(None));
141    /// ```
142    ///
143    /// # Versioning
144    ///
145    /// Available since 1.3.0.
146    #[must_use]
147    pub fn finite_or_negative_infinity(option: Option<T>) -> Infinitable<T> {
148        match option {
149            Some(x) => Finite(x),
150            None => NegativeInfinity,
151        }
152    }
153
154    /// Converts the value into a different type, based on the conversion of the
155    /// underlying type `T`.
156    ///
157    /// Infinite values are preserved as is, while finite values are converted
158    /// using [`into`] on the underlying value.
159    ///
160    /// [`into`]: Into::into
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// use infinitable::*;
166    /// let finite = Finite(5);
167    /// let finite64: Infinitable<i64> = finite.convert_into();
168    /// assert_eq!(Finite(5i64), finite64);
169    /// let infinite: Infinitable<i32> = Infinity;
170    /// let infinite64: Infinitable<i64> = infinite.convert_into();
171    /// assert_eq!(Infinity, infinite64);
172    /// ```
173    ///
174    /// # Versioning
175    ///
176    /// Available since 1.6.0.
177    #[must_use]
178    pub fn convert_into<U>(self) -> Infinitable<U>
179    where
180        T: Into<U>,
181    {
182        match self {
183            Finite(x) => Finite(x.into()),
184            Infinity => Infinity,
185            NegativeInfinity => NegativeInfinity,
186        }
187    }
188
189    /// Converts the value into a different type, based on the conversion of the
190    /// underlying type `T`.
191    ///
192    /// Infinite values are preserved as is, while finite values are converted
193    /// using [`try_into`] on the underlying value. Conversion of infinite
194    /// values always succeeds, while conversion of finite values may fail.
195    ///
196    /// [`try_into`]: TryInto::try_into
197    ///
198    /// # Examples
199    ///
200    /// ```
201    /// use infinitable::*;
202    /// use std::num::TryFromIntError;
203    /// let finite = Finite(1000);
204    /// let finite8: Result<Infinitable<i8>, TryFromIntError>
205    ///     = finite.try_convert_into();
206    /// assert!(finite8.is_err());
207    /// let infinite: Infinitable<i32> = Infinity;
208    /// let infinite8: Result<Infinitable<i8>, TryFromIntError>
209    ///     = infinite.try_convert_into();
210    /// assert_eq!(Ok(Infinity), infinite8);
211    /// ```
212    ///
213    /// # Versioning
214    ///
215    /// Available since 1.6.0.
216    #[must_use]
217    pub fn try_convert_into<U>(self) -> Result<Infinitable<U>, T::Error>
218    where
219        T: TryInto<U>,
220    {
221        match self {
222            Finite(x) => x.try_into().map(|y| Finite(y)),
223            Infinity => Ok(Infinity),
224            NegativeInfinity => Ok(NegativeInfinity),
225        }
226    }
227}
228
229impl<T> From<T> for Infinitable<T> {
230    /// Converts from a value `T` to [`Finite`] containing the underlying value.
231    ///
232    /// Note that there is no special handling for pre-existing infinite values.
233    /// Consider using [`from_f32`] or [`from_f64`] for floating-point numbers.
234    ///
235    /// # Examples
236    ///
237    /// ```
238    /// use infinitable::*;
239    ///
240    /// let finite = Infinitable::from(5);
241    /// assert_eq!(Finite(5), finite);
242    ///
243    /// // Warning: There is no special handling for pre-existing infinite values
244    /// let fp_infinity = Infinitable::from(f32::INFINITY);
245    /// assert_eq!(Finite(f32::INFINITY), fp_infinity);
246    /// assert_ne!(Infinity, fp_infinity);
247    /// ```
248    ///
249    /// # Versioning
250    ///
251    /// Available since 1.2.0.
252    fn from(value: T) -> Infinitable<T> {
253        Finite(value)
254    }
255}
256
257/// Partial order, when the underlying type `T` implements a partial order.
258///
259/// [`NegativeInfinity`] compares less than all other values,
260/// and [`Infinity`] compares greater than all other values.
261///
262/// # Examples
263///
264/// ```
265/// use infinitable::*;
266/// use std::cmp::Ordering;
267///
268/// let finite = Finite(5);
269/// let infinity = Infinity;
270/// let negative_infinity = NegativeInfinity;
271///
272/// assert_eq!(Some(Ordering::Less), finite.partial_cmp(&infinity));
273/// assert_eq!(Some(Ordering::Greater), finite.partial_cmp(&negative_infinity));
274/// ```
275///
276/// # Versioning
277///
278/// Available since 1.0.0.
279impl<T> PartialOrd for Infinitable<T>
280where
281    T: PartialOrd,
282{
283    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
284        match cmp_initial(self, other) {
285            CmpInitialResult::Infinite(o) => Some(o),
286            CmpInitialResult::Finite(x, y) => x.partial_cmp(y),
287        }
288    }
289}
290
291/// Total order, when the underlying type `T` implements a total order.
292///
293/// [`NegativeInfinity`] compares less than all other values,
294/// and [`Infinity`] compares greater than all other values.
295///
296/// # Examples
297///
298/// ```
299/// use infinitable::*;
300/// use std::cmp::Ordering;
301///
302/// let finite = Finite(5);
303/// let infinity = Infinity;
304/// let negative_infinity = NegativeInfinity;
305///
306/// assert_eq!(Ordering::Less, finite.cmp(&infinity));
307/// assert_eq!(Ordering::Greater, finite.cmp(&negative_infinity));
308/// ```
309///
310/// # Versioning
311///
312/// Available since 1.0.0.
313impl<T> Ord for Infinitable<T>
314where
315    T: Ord,
316{
317    fn cmp(&self, other: &Self) -> Ordering {
318        match cmp_initial(self, other) {
319            CmpInitialResult::Infinite(o) => o,
320            CmpInitialResult::Finite(x, y) => x.cmp(y),
321        }
322    }
323}
324
325enum CmpInitialResult<'a, T> {
326    Infinite(Ordering),
327    Finite(&'a T, &'a T),
328}
329
330fn cmp_initial<'a, T>(x: &'a Infinitable<T>, y: &'a Infinitable<T>) -> CmpInitialResult<'a, T> {
331    match (x, y) {
332        (Infinity, Infinity) | (NegativeInfinity, NegativeInfinity) => {
333            CmpInitialResult::Infinite(Ordering::Equal)
334        }
335        (Infinity, _) | (_, NegativeInfinity) => CmpInitialResult::Infinite(Ordering::Greater),
336        (NegativeInfinity, _) | (_, Infinity) => CmpInitialResult::Infinite(Ordering::Less),
337        (Finite(xf), Finite(yf)) => CmpInitialResult::Finite(xf, yf),
338    }
339}
340
341impl<T> Add for Infinitable<T>
342where
343    T: Add,
344{
345    type Output = Infinitable<T::Output>;
346
347    /// Adds two values.
348    ///
349    /// The addition operation follows these rules:
350    ///
351    /// | self               | rhs                | result                |
352    /// |--------------------|--------------------|-----------------------|
353    /// | `Finite`           | `Finite`           | `Finite` (add values) |
354    /// | `Finite`           | `Infinity`         | `Infinity`            |
355    /// | `Finite`           | `NegativeInfinity` | `NegativeInfinity`    |
356    /// | `Infinity`         | `Finite`           | `Infinity`            |
357    /// | `Infinity`         | `Infinity`         | `Infinity`            |
358    /// | `Infinity`         | `NegativeInfinity` | Undefined (panic)     |
359    /// | `NegativeInfinity` | `Finite`           | `NegativeInfinity`    |
360    /// | `NegativeInfinity` | `Infinity`         | Undefined (panic)     |
361    /// | `NegativeInfinity` | `NegativeInfinity` | `NegativeInfinity`    |
362    ///
363    /// # Examples
364    ///
365    /// ```
366    /// use infinitable::*;
367    ///
368    /// assert_eq!(Finite(5), Finite(2) + Finite(3));
369    /// assert_eq!(Infinity, Finite(1) + Infinity);
370    /// assert_eq!(NegativeInfinity, NegativeInfinity + Finite(1));
371    /// ```
372    ///
373    /// The addition operation panics with `Infinity` and `NegativeInfinity`:
374    ///
375    /// ```should_panic
376    /// use infinitable::*;
377    ///
378    /// let infinity: Infinitable<i32> = Infinity;
379    /// let negative_infinity: Infinitable<i32> = NegativeInfinity;
380    /// let _ = infinity + negative_infinity;
381    /// ```
382    ///
383    /// # Panics
384    ///
385    /// Panics if the operands consist of `Infinity` and `NegativeInfinity`.
386    ///
387    /// # Versioning
388    ///
389    /// Available since 1.5.0.
390    fn add(self, rhs: Infinitable<T>) -> Infinitable<T::Output> {
391        match (self, rhs) {
392            (Infinity, NegativeInfinity) | (NegativeInfinity, Infinity) => {
393                panic!("Cannot add infinity and negative infinity")
394            }
395            (Finite(lf), Finite(rf)) => Finite(lf.add(rf)),
396            (Infinity, _) | (_, Infinity) => Infinity,
397            (NegativeInfinity, _) | (_, NegativeInfinity) => NegativeInfinity,
398        }
399    }
400}
401
402impl<T> Sub for Infinitable<T>
403where
404    T: Sub,
405{
406    type Output = Infinitable<T::Output>;
407
408    /// Subtracts two values.
409    ///
410    /// The subtraction operation follows these rules:
411    ///
412    /// | self               | rhs                | result                     |
413    /// |--------------------|--------------------|----------------------------|
414    /// | `Finite`           | `Finite`           | `Finite` (subtract values) |
415    /// | `Finite`           | `Infinity`         | `NegativeInfinity`         |
416    /// | `Finite`           | `NegativeInfinity` | `Infinity`                 |
417    /// | `Infinity`         | `Finite`           | `Infinity`                 |
418    /// | `Infinity`         | `Infinity`         | Undefined (panic)          |
419    /// | `Infinity`         | `NegativeInfinity` | `Infinity`                 |
420    /// | `NegativeInfinity` | `Finite`           | `NegativeInfinity`         |
421    /// | `NegativeInfinity` | `Infinity`         | `NegativeInfinity`         |
422    /// | `NegativeInfinity` | `NegativeInfinity` | Undefined (panic)          |
423    ///
424    /// # Examples
425    ///
426    /// ```
427    /// use infinitable::*;
428    ///
429    /// assert_eq!(Finite(3), Finite(5) - Finite(2));
430    /// assert_eq!(Infinity, Infinity - Finite(1));
431    /// assert_eq!(Infinity, Finite(1) - NegativeInfinity);
432    /// assert_eq!(NegativeInfinity, NegativeInfinity - Finite(1));
433    /// assert_eq!(NegativeInfinity, Finite(1) - Infinity);
434    /// ```
435    ///
436    /// The subraction operation panics when an infinite value is subtracted
437    /// from itself:
438    ///
439    /// ```should_panic
440    /// use infinitable::*;
441    ///
442    /// let infinity: Infinitable<i32> = Infinity;
443    /// let _ = infinity - infinity;
444    /// ```
445    ///
446    /// # Panics
447    ///
448    /// Panics if the operands are both `Infinity` or both `NegativeInfinity`.
449    ///
450    /// # Versioning
451    ///
452    /// Available since 1.5.0.
453    fn sub(self, rhs: Infinitable<T>) -> Infinitable<T::Output> {
454        match (self, rhs) {
455            (Infinity, Infinity) | (NegativeInfinity, NegativeInfinity) => {
456                panic!("Cannot subtract infinite value from itself")
457            }
458            (Finite(lf), Finite(rf)) => Finite(lf.sub(rf)),
459            (Infinity, _) | (_, NegativeInfinity) => Infinity,
460            (NegativeInfinity, _) | (_, Infinity) => NegativeInfinity,
461        }
462    }
463}
464
465impl<T> Mul for Infinitable<T>
466where
467    T: Mul + Zero + PartialOrd,
468{
469    type Output = Infinitable<<T as Mul>::Output>;
470
471    /// Multiplies two values.
472    ///
473    /// The multiplication operation follows these rules:
474    ///
475    /// | self               | rhs                | result                     |
476    /// |--------------------|--------------------|----------------------------|
477    /// | `Finite`           | `Finite`           | `Finite` (multiply values) |
478    /// | `Finite` (> 0)     | `Infinity`         | `Infinity`                 |
479    /// | `Finite` (~ 0)     | `Infinity`         | Undefined (panic)          |
480    /// | `Finite` (< 0)     | `Infinity`         | `NegativeInfinity`         |
481    /// | `Finite` (> 0)     | `NegativeInfinity` | `NegativeInfinity`         |
482    /// | `Finite` (~ 0)     | `NegativeInfinity` | Undefined (panic)          |
483    /// | `Finite` (< 0)     | `NegativeInfinity` | `Infinity`                 |
484    /// | `Infinity`         | `Finite` (> 0)     | `Infinity`                 |
485    /// | `Infinity`         | `Finite` (~ 0)     | Undefined (panic)          |
486    /// | `Infinity`         | `Finite` (< 0)     | `NegativeInfinity`         |
487    /// | `Infinity`         | `Infinity`         | `Infinity`                 |
488    /// | `Infinity`         | `NegativeInfinity` | `NegativeInfinity`         |
489    /// | `NegativeInfinity` | `Finite` (> 0)     | `NegativeInfinity`         |
490    /// | `NegativeInfinity` | `Finite` (~ 0)     | Undefined (panic)          |
491    /// | `NegativeInfinity` | `Finite` (< 0)     | `Infinity`                 |
492    /// | `NegativeInfinity` | `Infinity`         | `NegativeInfinity`         |
493    /// | `NegativeInfinity` | `NegativeInfinity` | `Infinity`                 |
494    ///
495    /// (In the table, "~ 0" refers to a value that is either equal to or
496    /// unordered with zero.)
497    ///
498    /// # Examples
499    ///
500    /// ```
501    /// use infinitable::*;
502    ///
503    /// assert_eq!(Finite(6), Finite(2) * Finite(3));
504    /// assert_eq!(Infinity, Infinity * Finite(2));
505    /// assert_eq!(Infinity, Finite(-1) * NegativeInfinity);
506    /// assert_eq!(NegativeInfinity, NegativeInfinity * Finite(2));
507    /// assert_eq!(NegativeInfinity, Finite(-1) * Infinity);
508    /// ```
509    ///
510    /// The multiplication operation panics when an infinite value is multiplied
511    /// with zero:
512    ///
513    /// ```should_panic
514    /// use infinitable::*;
515    ///
516    /// let infinity: Infinitable<i32> = Infinity;
517    /// let _ = infinity * Finite(0);
518    /// ```
519    ///
520    /// # Panics
521    ///
522    /// Panics if one of the operands is `Infinity` or `NegativeInfinity` and
523    /// the other is a `Finite` value with an underlying value equal to or
524    /// unordered with zero.
525    ///
526    /// # Versioning
527    ///
528    /// Available since 1.5.0.
529    fn mul(self, rhs: Infinitable<T>) -> Infinitable<<T as Mul>::Output> {
530        match (self, rhs) {
531            (Infinity, Infinity) | (NegativeInfinity, NegativeInfinity) => Infinity,
532            (Infinity, NegativeInfinity) | (NegativeInfinity, Infinity) => NegativeInfinity,
533            (Infinity, Finite(x)) | (Finite(x), Infinity) => match x.partial_cmp(&T::zero()) {
534                Some(Ordering::Greater) => Infinity,
535                Some(Ordering::Less) => NegativeInfinity,
536                _ => panic!("Cannot multiply infinite value and zero or unordered value"),
537            },
538            (NegativeInfinity, Finite(x)) | (Finite(x), NegativeInfinity) => {
539                match x.partial_cmp(&T::zero()) {
540                    Some(Ordering::Greater) => NegativeInfinity,
541                    Some(Ordering::Less) => Infinity,
542                    _ => panic!("Cannot multiply infinite value and zero or unordered value"),
543                }
544            }
545            (Finite(lf), Finite(rf)) => Finite(lf.mul(rf)),
546        }
547    }
548}
549
550impl<T> Div for Infinitable<T>
551where
552    T: Div + Zero + PartialOrd,
553    <T as Div>::Output: Zero,
554{
555    type Output = Infinitable<<T as Div>::Output>;
556
557    /// Divides two values.
558    ///
559    /// The division operation follows these rules:
560    ///
561    /// | self               | rhs                | result                     |
562    /// |--------------------|--------------------|----------------------------|
563    /// | `Finite` (> 0)     | `Finite` (~ 0)     | `Infinity`                 |
564    /// | `Finite` (~ 0)     | `Finite` (~ 0)     | Undefined (panic)          |
565    /// | `Finite` (< 0)     | `Finite` (~ 0)     | `NegativeInfinity`         |
566    /// | `Finite`           | `Finite` (<> 0)    | `Finite` (divide values)   |
567    /// | `Finite`           | `Infinity`         | Zero                       |
568    /// | `Finite`           | `NegativeInfinity` | Zero                       |
569    /// | `Infinity`         | `Finite` (> 0)     | `Infinity`                 |
570    /// | `Infinity`         | `Finite` (~ 0)     | `Infinity`                 |
571    /// | `Infinity`         | `Finite` (< 0)     | `NegativeInfinity`         |
572    /// | `Infinity`         | `Infinity`         | Undefined (panic)          |
573    /// | `Infinity`         | `NegativeInfinity` | Undefined (panic)          |
574    /// | `NegativeInfinity` | `Finite` (> 0)     | `NegativeInfinity`         |
575    /// | `NegativeInfinity` | `Finite` (~ 0)     | `NegativeInfinity`         |
576    /// | `NegativeInfinity` | `Finite` (< 0)     | `Infinity`                 |
577    /// | `NegativeInfinity` | `Infinity`         | Undefined (panic)          |
578    /// | `NegativeInfinity` | `NegativeInfinity` | Undefined (panic)          |
579    ///
580    /// (In the table, "~ 0" refers to a value that is either equal to or
581    /// unordered with zero, and "<> 0" refers to a value that is either
582    /// greater than or less than zero.)
583    ///
584    /// # Examples
585    ///
586    /// ```
587    /// use infinitable::*;
588    ///
589    /// assert_eq!(Finite(3), Finite(6) / Finite(2));
590    /// assert_eq!(Infinity, Infinity / Finite(1));
591    /// assert_eq!(Infinity, NegativeInfinity / Finite(-2));
592    /// assert_eq!(NegativeInfinity, NegativeInfinity / Finite(1));
593    /// assert_eq!(NegativeInfinity, Infinity / Finite(-2));
594    /// assert_eq!(Finite(0), Finite(1) / Infinity);
595    /// assert_eq!(Finite(0), Finite(1) / NegativeInfinity);
596    /// ```
597    ///
598    /// The division operation panics when an infinite value is divided by
599    /// another infinite value, or when zero is divided by itself:
600    ///
601    /// ```should_panic
602    /// use infinitable::*;
603    ///
604    /// let infinity: Infinitable<i32> = Infinity;
605    /// let _ = infinity / infinity;
606    /// ```
607    ///
608    /// ```should_panic
609    /// use infinitable::*;
610    ///
611    /// let _ = Finite(0) / Finite(0);
612    /// ```
613    ///
614    /// # Panics
615    ///
616    /// Panics if both operands are either `Infinity` or `NegativeInfinity`, or
617    /// both operands are `Finite` with an underlying value equal to or
618    /// unordered with zero.
619    ///
620    /// # Versioning
621    ///
622    /// Available since 1.5.0.
623    fn div(self, rhs: Infinitable<T>) -> Infinitable<<T as Div>::Output> {
624        match (self, rhs) {
625            (Infinity, Infinity)
626            | (NegativeInfinity, NegativeInfinity)
627            | (Infinity, NegativeInfinity)
628            | (NegativeInfinity, Infinity) => panic!("Cannot divide two infinite values"),
629            (Infinity, Finite(x)) => match x.partial_cmp(&T::zero()) {
630                Some(Ordering::Less) => NegativeInfinity,
631                _ => Infinity,
632            },
633            (NegativeInfinity, Finite(x)) => match x.partial_cmp(&T::zero()) {
634                Some(Ordering::Less) => Infinity,
635                _ => NegativeInfinity,
636            },
637            (Finite(_), Infinity) | (Finite(_), NegativeInfinity) => {
638                Finite(<T as Div>::Output::zero())
639            }
640            (Finite(lf), Finite(rf)) => match rf.partial_cmp(&T::zero()) {
641                Some(Ordering::Greater) | Some(Ordering::Less) => Finite(lf.div(rf)),
642                _ => match lf.partial_cmp(&T::zero()) {
643                    Some(Ordering::Greater) => Infinity,
644                    Some(Ordering::Less) => NegativeInfinity,
645                    _ => panic!("Cannot divide two zeros or unordered values"),
646                },
647            },
648        }
649    }
650}
651
652impl<T> Neg for Infinitable<T>
653where
654    T: Neg,
655{
656    type Output = Infinitable<T::Output>;
657
658    /// Negates the value, when the underlying type `T` supports negation.
659    ///
660    /// [`Infinity`] is negated to [`NegativeInfinity`] (and vice versa),
661    /// and [`Finite`] is negated based on the underlying value.
662    ///
663    /// # Examples
664    ///
665    /// ```
666    /// use infinitable::*;
667    ///
668    /// let finite = Finite(5);
669    /// assert_eq!(Finite(-5), -finite);
670    /// let infinity: Infinitable<i32> = Infinity;
671    /// assert_eq!(NegativeInfinity, -infinity);
672    /// let negative_infinity: Infinitable<i32> = NegativeInfinity;
673    /// assert_eq!(Infinity, -negative_infinity);
674    /// ```
675    ///
676    /// # Versioning
677    ///
678    /// Available since 1.3.0.
679    fn neg(self) -> Infinitable<T::Output> {
680        match self {
681            Finite(x) => Finite(-x),
682            Infinity => NegativeInfinity,
683            NegativeInfinity => Infinity,
684        }
685    }
686}
687
688impl<T> Display for Infinitable<T>
689where
690    T: Display,
691{
692    /// Formats the value, when the underlying type `T` supports formatting.
693    ///
694    /// [`Infinity`] is formatted to `"inf"`, [`NegativeInfinity`] is formatted
695    /// to `"-inf"`, and [`Finite`] is formatted based on the underlying value.
696    ///
697    /// # Examples
698    ///
699    /// ```
700    /// use infinitable::*;
701    ///
702    /// let finite = Finite(5);
703    /// assert_eq!("5", format!("{}", finite));
704    /// let infinity: Infinitable<i32> = Infinity;
705    /// assert_eq!("inf", format!("{}", infinity));
706    /// let negative_infinity: Infinitable<i32> = NegativeInfinity;
707    /// assert_eq!("-inf", format!("{}", negative_infinity));
708    /// ```
709    ///
710    /// # Versioning
711    ///
712    /// Available since 1.2.0.
713    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
714        match self {
715            Finite(x) => write!(f, "{}", x),
716            Infinity => write!(f, "inf"),
717            NegativeInfinity => write!(f, "-inf"),
718        }
719    }
720}
721
722/// Converts from [`f32`] value to an optional [`Infinitable<f32>`],
723/// accounting for floating-point infinities and NaN.
724///
725/// The value is converted as follows:
726///
727/// | value             | result                                   |
728/// |-------------------|------------------------------------------|
729/// | Finite value `x`  | <code>[Some]\([Finite]\(x))</code>       |
730/// | Positive infinity | <code>[Some]\([Infinity])</code>         |
731/// | Negative infinity | <code>[Some]\([NegativeInfinity])</code> |
732/// | NaN               | [`None`]                                 |
733///
734/// # Examples
735///
736/// ```
737/// use infinitable::*;
738///
739/// let finite = from_f32(5.0);
740/// assert_eq!(Some(Finite(5.0)), finite);
741/// let infinity = from_f32(f32::INFINITY);
742/// assert_eq!(Some(Infinity), infinity);
743/// let nan = from_f32(f32::NAN);
744/// assert_eq!(None, nan);
745/// ```
746///
747/// # Versioning
748///
749/// Available since 1.5.0.
750pub fn from_f32(value: f32) -> Option<Infinitable<f32>> {
751    if value.is_finite() {
752        Some(Finite(value))
753    } else if value.is_nan() {
754        None
755    } else if value.is_sign_positive() {
756        Some(Infinity)
757    } else {
758        Some(NegativeInfinity)
759    }
760}
761
762/// Converts from [`f64`] value to an optional [`Infinitable<f64>`],
763/// accounting for floating-point infinities and NaN.
764///
765/// The value is converted as follows:
766///
767/// | value             | result                                   |
768/// |-------------------|------------------------------------------|
769/// | Finite value `x`  | <code>[Some]\([Finite]\(x))</code>       |
770/// | Positive infinity | <code>[Some]\([Infinity])</code>         |
771/// | Negative infinity | <code>[Some]\([NegativeInfinity])</code> |
772/// | NaN               | [`None`]                                 |
773///
774/// # Examples
775///
776/// ```
777/// use infinitable::*;
778///
779/// let finite = from_f64(5.0);
780/// assert_eq!(Some(Finite(5.0)), finite);
781/// let infinity = from_f64(f64::INFINITY);
782/// assert_eq!(Some(Infinity), infinity);
783/// let nan = from_f64(f64::NAN);
784/// assert_eq!(None, nan);
785/// ```
786///
787/// # Versioning
788///
789/// Available since 1.5.0.
790pub fn from_f64(value: f64) -> Option<Infinitable<f64>> {
791    if value.is_finite() {
792        Some(Finite(value))
793    } else if value.is_nan() {
794        None
795    } else if value.is_sign_positive() {
796        Some(Infinity)
797    } else {
798        Some(NegativeInfinity)
799    }
800}