number_theory/
result.rs

1/// Enum returned in checked functions returning any errors of evaluation 
2#[non_exhaustive]
3#[derive(Clone,Debug,PartialEq,Eq)]
4pub enum NTResult<T: Sized + Clone>{
5/// Evaluation is knowable and was calculated in the bounds. FFI return 0
6  Eval(T), //  Flag 0
7/// Solution Exists but does not fit in datatype. FFI return 1   
8  Overflow,  //  Flag 1
9/// Solution Does Not Exist. FFI return 2  
10  DNE,       //  Flag 2
11/// Solution Exists but is Infinitely large. FFI return 3   
12  Infinite,  //  Flag 3
13/// Solutions exist but there are infinite number of them (all elements of Z). FFI return 4
14  InfiniteSet, // Flag 4
15/// Computation exceeds some practical bound. FFI return 5
16  CompExceeded,  //  Flag 5
17/// Overflowed during computation result does not necessarily exceed the datatype. FFI return 6
18  CompOverflow, // Flag 6
19/// Function is not defined for the inputs. FFI return 7
20  Undefined,  // Flag 7
21}
22
23
24impl<T: Sized + Clone + Default> NTResult<T>{
25
26/// Returns the Evaluated number
27 pub fn unwrap(&self) -> T{
28    match self{
29    NTResult::Eval(x) => x.clone(),
30    NTResult::Overflow=> panic!("Result does not fit in datatype"),
31    NTResult::DNE => panic!("Does Not Exist"),
32    NTResult::Infinite => panic!("Infinitely large solution"),
33    NTResult::InfiniteSet => panic!("Infinite number of solutions"),
34    NTResult::CompExceeded => panic!("Computation exceeded hardcoded limit"),
35    NTResult::CompOverflow => panic!("Overflowed during computation"),
36    NTResult::Undefined => panic!("Undefined solution"),
37    }
38 }
39 
40 /// Returns the result or panics with the selected message
41 pub fn expect(&self, signal: &str)-> T{
42    match self{
43     NTResult::Eval(x) => x.clone(),
44     _=> panic!("{}",signal)
45    }
46 }
47 /// Returns the result or the selected default
48 pub fn unwrap_or(&self, res: T) -> T{
49    match self{
50     NTResult::Eval(x) => x.clone(),
51     _=> res,
52    }
53 }
54 /// Checks if the result is infinitely large
55 pub fn is_infinite(&self) -> bool{
56   match self{
57   NTResult::Infinite => true,
58     _=> false,
59   }
60 }
61 /// Checks if the result is an infinite set
62 pub fn is_infiniteset(&self) -> bool{
63   match self{
64   NTResult::InfiniteSet => true,
65     _=> false,
66   }
67 }
68 /// Checks if the solution to the function exists
69 pub fn is_dne(&self) -> bool{
70   match self{
71   NTResult::DNE => true,
72     _=> false,
73   }
74 }
75 /// Checks if the result exceeds the datatype max
76 pub fn is_overflow(&self) -> bool{
77   match self{
78   NTResult::Overflow => true,
79     _=> false,
80   }
81 }
82 /// Checks if there was an overflow during computation
83 pub fn is_comp_overflow(&self) -> bool{
84   match self{
85   NTResult::CompOverflow => true,
86     _=> false,
87   }
88 }
89 /// Checks if the Computation exceeded 
90 pub fn is_comp_exceeded(&self) -> bool{
91   match self{
92   NTResult::CompExceeded => true,
93     _=> false,
94   }
95 }
96  /// Checks if the result is undefined 
97 pub fn is_undefined(&self) -> bool{
98   match self{
99   NTResult::Undefined => true,
100     _=> false,
101   }
102 }
103 /** Converts from Option to NTResult. None values are converted to the selected NTResult variant
104 ```
105  use number_theory::NumberTheory;
106  use number_theory::NTResult; 
107  
108  // A None is returned here due to exceeding the i8::MAX
109  let res = 255u8.checked_add(1);
110  // The None option is converted to an NTResult::Overflow
111   
112  let convert = NTResult::from_option(res,NTResult::Overflow);
113 
114  assert_eq!(convert, NTResult::Overflow);
115  
116  // An Some result is converted to Eval 
117  
118    let res = 254u8.checked_add(1);
119    let convert = NTResult::from_option(res,NTResult::Overflow);
120    
121      assert_eq!(convert, NTResult::Eval(255));
122 ```
123 */
124 pub fn from_option( opt: Option<T>, ntvariant: Self) -> Self{
125     match opt{
126       Some(x) => NTResult::Eval(x),
127       None => ntvariant,
128     }
129 }
130
131/// Maps within the Enum
132 pub fn map<U: Clone,F: FnOnce(T) -> U>(&self, func : F) -> NTResult<U>{
133   match self {
134     NTResult::Eval(x) => NTResult::Eval((func)(x.clone())),
135     NTResult::Overflow => NTResult::Overflow,
136     NTResult::DNE => NTResult::DNE,
137     NTResult::Infinite => NTResult::Infinite,
138     NTResult::InfiniteSet => NTResult::InfiniteSet,
139     NTResult::CompExceeded => NTResult::CompExceeded,
140     NTResult::CompOverflow => NTResult::CompOverflow,
141     NTResult::Undefined => NTResult::Undefined,
142   }
143 }
144 /** Return value and flag for FFI bindings
145 ```
146 use number_theory::NumberTheory;
147   // Attempt to factor 0
148   let res = 0.factor();
149   // Fails and returns a NTResult  
150   // and 4 for C api binding
151  assert_eq!(res.ffi().1,4);
152   
153   let res = 1.factor(); 
154   // Likewise an DNE NTResult gets converted to a vec and 2
155   assert_eq!(res.ffi().1,2);
156   
157   let res = 9.factor();
158   // Finally a fully factorable integer gets a vector and the 0 flag
159   assert_eq!(res.ffi().1,0);
160 ```  
161 
162 */ 
163 pub fn ffi(&self)-> (T,u8){
164    match self {
165     NTResult::Eval(x) => (x.clone(),0u8),
166     NTResult::Overflow => (T::default(),1u8),
167     NTResult::DNE => (T::default(),2u8),
168     NTResult::Infinite => (T::default(),3u8),
169     NTResult::InfiniteSet => (T::default(),4u8),
170     NTResult::CompExceeded => (T::default(),5u8),
171     NTResult::CompOverflow => (T::default(),6u8),
172     NTResult::Undefined => (T::default(),7u8),
173   }
174 }
175
176}
177
178impl<T: Clone + Default + Sized + std::fmt::Display > std::fmt::Display for NTResult<T>{
179    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
180       match self{
181       
182       NTResult::Eval(x) => write!(f,"{}",x),
183       NTResult::Overflow => write!(f,"Overflow"),
184       NTResult::DNE => write!(f,"DNE"),
185       NTResult::Infinite => write!(f,"Infinite"),
186       NTResult::InfiniteSet => write!(f,"Infinite solutions"),
187       NTResult::CompExceeded => write!(f,"Exceeded computation bound"),
188       NTResult::CompOverflow => write!(f,"Overflowed during computation"),
189       NTResult::Undefined => write!(f,"Undefined"),
190       }
191    }
192   }