Skip to main content

malachite_nz/gaussian_integer/conversion/
natural_from_gaussian_integer.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::gaussian_integer::GaussianInteger;
10use crate::natural::Natural;
11use malachite_base::num::conversion::traits::ConvertibleFrom;
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub struct NaturalFromGaussianIntegerError;
15
16impl TryFrom<GaussianInteger> for Natural {
17    type Error = NaturalFromGaussianIntegerError;
18
19    /// Converts a [`GaussianInteger`] to a [`Natural`], taking the [`GaussianInteger`] by value. If
20    /// the [`GaussianInteger`] is not real or is negative, an error is returned.
21    ///
22    /// # Worst-case complexity
23    /// Constant time and additional memory.
24    ///
25    /// # Examples
26    /// ```
27    /// use malachite_nz::gaussian_integer::GaussianInteger;
28    /// use malachite_nz::gaussian_integer::conversion::natural_from_gaussian_integer::*;
29    /// use malachite_nz::natural::Natural;
30    /// use std::str::FromStr;
31    ///
32    /// let x = GaussianInteger::from_str("123").unwrap();
33    /// assert_eq!(Natural::try_from(x).unwrap(), 123);
34    ///
35    /// let x = GaussianInteger::from_str("-123").unwrap();
36    /// assert_eq!(Natural::try_from(x), Err(NaturalFromGaussianIntegerError));
37    ///
38    /// let x = GaussianInteger::from_str("2-3i").unwrap();
39    /// assert_eq!(Natural::try_from(x), Err(NaturalFromGaussianIntegerError));
40    /// ```
41    fn try_from(x: GaussianInteger) -> Result<Self, Self::Error> {
42        if x.imaginary == 0u32 {
43            Self::try_from(x.real).map_err(|_| NaturalFromGaussianIntegerError)
44        } else {
45            Err(NaturalFromGaussianIntegerError)
46        }
47    }
48}
49
50impl TryFrom<&GaussianInteger> for Natural {
51    type Error = NaturalFromGaussianIntegerError;
52
53    /// Converts a [`GaussianInteger`] to a [`Natural`], taking the [`GaussianInteger`] by
54    /// reference. If the [`GaussianInteger`] is not real or is negative, an error is returned.
55    ///
56    /// # Worst-case complexity
57    /// $T(n) = O(n)$
58    ///
59    /// $M(n) = O(n)$
60    ///
61    /// where $T$ is time, $M$ is additional memory, and $n$ is `x.real.significant_bits()`.
62    ///
63    /// # Examples
64    /// ```
65    /// use malachite_nz::gaussian_integer::GaussianInteger;
66    /// use malachite_nz::gaussian_integer::conversion::natural_from_gaussian_integer::*;
67    /// use malachite_nz::natural::Natural;
68    /// use std::str::FromStr;
69    ///
70    /// let x = GaussianInteger::from_str("123").unwrap();
71    /// assert_eq!(Natural::try_from(&x).unwrap(), 123);
72    ///
73    /// let x = GaussianInteger::from_str("-123").unwrap();
74    /// assert_eq!(Natural::try_from(&x), Err(NaturalFromGaussianIntegerError));
75    ///
76    /// let x = GaussianInteger::from_str("2-3i").unwrap();
77    /// assert_eq!(Natural::try_from(&x), Err(NaturalFromGaussianIntegerError));
78    /// ```
79    fn try_from(x: &GaussianInteger) -> Result<Self, Self::Error> {
80        if x.imaginary == 0u32 {
81            Self::try_from(&x.real).map_err(|_| NaturalFromGaussianIntegerError)
82        } else {
83            Err(NaturalFromGaussianIntegerError)
84        }
85    }
86}
87
88impl ConvertibleFrom<&GaussianInteger> for Natural {
89    /// Determines whether a [`GaussianInteger`] can be converted to a [`Natural`] (that is, whether
90    /// it is real and non-negative), taking the [`GaussianInteger`] by reference.
91    ///
92    /// # Worst-case complexity
93    /// Constant time and additional memory.
94    ///
95    /// # Examples
96    /// ```
97    /// use malachite_base::num::conversion::traits::ConvertibleFrom;
98    /// use malachite_nz::gaussian_integer::GaussianInteger;
99    /// use malachite_nz::natural::Natural;
100    /// use std::str::FromStr;
101    ///
102    /// let x = GaussianInteger::from_str("123").unwrap();
103    /// assert_eq!(Natural::convertible_from(&x), true);
104    ///
105    /// let x = GaussianInteger::from_str("-123").unwrap();
106    /// assert_eq!(Natural::convertible_from(&x), false);
107    ///
108    /// let x = GaussianInteger::from_str("2-3i").unwrap();
109    /// assert_eq!(Natural::convertible_from(&x), false);
110    /// ```
111    #[inline]
112    fn convertible_from(x: &GaussianInteger) -> bool {
113        x.imaginary == 0u32 && Self::convertible_from(&x.real)
114    }
115}