malachite_nz/gaussian_integer/conversion/integer_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::integer::Integer;
11use malachite_base::num::conversion::traits::ConvertibleFrom;
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub struct IntegerFromGaussianIntegerError;
15
16impl TryFrom<GaussianInteger> for Integer {
17 type Error = IntegerFromGaussianIntegerError;
18
19 /// Converts a [`GaussianInteger`] to an [`Integer`], taking the [`GaussianInteger`] by value.
20 /// If the [`GaussianInteger`] is not real, 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::integer_from_gaussian_integer::*;
29 /// use malachite_nz::integer::Integer;
30 /// use std::str::FromStr;
31 ///
32 /// let x = GaussianInteger::from_str("123").unwrap();
33 /// assert_eq!(Integer::try_from(x).unwrap(), 123);
34 ///
35 /// let x = GaussianInteger::from_str("-123").unwrap();
36 /// assert_eq!(Integer::try_from(x).unwrap(), -123);
37 ///
38 /// let x = GaussianInteger::from_str("2-3i").unwrap();
39 /// assert_eq!(Integer::try_from(x), Err(IntegerFromGaussianIntegerError));
40 /// ```
41 fn try_from(x: GaussianInteger) -> Result<Self, Self::Error> {
42 if x.imaginary == 0u32 {
43 Ok(x.real)
44 } else {
45 Err(IntegerFromGaussianIntegerError)
46 }
47 }
48}
49
50impl TryFrom<&GaussianInteger> for Integer {
51 type Error = IntegerFromGaussianIntegerError;
52
53 /// Converts a [`GaussianInteger`] to an [`Integer`], taking the [`GaussianInteger`] by
54 /// reference. If the [`GaussianInteger`] is not real, 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::integer_from_gaussian_integer::*;
67 /// use malachite_nz::integer::Integer;
68 /// use std::str::FromStr;
69 ///
70 /// let x = GaussianInteger::from_str("123").unwrap();
71 /// assert_eq!(Integer::try_from(&x).unwrap(), 123);
72 ///
73 /// let x = GaussianInteger::from_str("-123").unwrap();
74 /// assert_eq!(Integer::try_from(&x).unwrap(), -123);
75 ///
76 /// let x = GaussianInteger::from_str("2-3i").unwrap();
77 /// assert_eq!(Integer::try_from(&x), Err(IntegerFromGaussianIntegerError));
78 /// ```
79 fn try_from(x: &GaussianInteger) -> Result<Self, Self::Error> {
80 if x.imaginary == 0u32 {
81 Ok(x.real.clone())
82 } else {
83 Err(IntegerFromGaussianIntegerError)
84 }
85 }
86}
87
88impl ConvertibleFrom<&GaussianInteger> for Integer {
89 /// Determines whether a [`GaussianInteger`] can be converted to an [`Integer`] (that is,
90 /// whether it is real), 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::integer::Integer;
100 /// use std::str::FromStr;
101 ///
102 /// let x = GaussianInteger::from_str("123").unwrap();
103 /// assert_eq!(Integer::convertible_from(&x), true);
104 ///
105 /// let x = GaussianInteger::from_str("-123").unwrap();
106 /// assert_eq!(Integer::convertible_from(&x), true);
107 ///
108 /// let x = GaussianInteger::from_str("2-3i").unwrap();
109 /// assert_eq!(Integer::convertible_from(&x), false);
110 /// ```
111 #[inline]
112 fn convertible_from(x: &GaussianInteger) -> bool {
113 x.imaginary == 0u32
114 }
115}