use super::PolyOverQ;
use crate::{macros::for_others::implement_for_owned, traits::GetCoefficient};
use core::fmt;
use flint_sys::fmpq_poly::fmpq_poly_get_str;
use std::ffi::CStr;
impl From<&PolyOverQ> for String {
fn from(value: &PolyOverQ) -> Self {
value.to_string()
}
}
implement_for_owned!(PolyOverQ, String, From);
impl fmt::Display for PolyOverQ {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let c_str_ptr = unsafe { fmpq_poly_get_str(&self.poly) };
let return_str = unsafe { CStr::from_ptr(c_str_ptr).to_str().unwrap().to_owned() };
unsafe { libc::free(c_str_ptr as *mut libc::c_void) };
write!(f, "{return_str}")
}
}
impl PolyOverQ {
pub fn to_string_decimal(&self, nr_decimal_digits: usize) -> String {
let degree = self.get_degree() + 1;
let mut poly_string = format!("{degree} ");
for i in 0..degree {
let entry = unsafe { self.get_coeff_unchecked(i) };
let entry_string = entry.to_string_decimal(nr_decimal_digits);
poly_string.push_str(&entry_string);
poly_string.push(' ');
}
poly_string = poly_string.trim().to_string();
poly_string
}
}
#[cfg(test)]
mod test_to_string_decimal {
use super::PolyOverQ;
use std::str::FromStr;
#[test]
fn different_degrees() {
let a = PolyOverQ::from_str("0").unwrap();
let b = PolyOverQ::from_str("1 1/3").unwrap();
let c = PolyOverQ::from_str("3 1/3 0 -5/3").unwrap();
let a_0 = a.to_string_decimal(0);
let a_1 = a.to_string_decimal(1);
let b_0 = b.to_string_decimal(0);
let b_2 = b.to_string_decimal(2);
let c_0 = c.to_string_decimal(0);
let c_1 = c.to_string_decimal(1);
assert_eq!("0", a_0);
assert_eq!("0", a_1);
assert_eq!("1 0", b_0);
assert_eq!("1 0.33", b_2);
assert_eq!("3 0 0 -2", c_0);
assert_eq!("3 0.3 0.0 -1.7", c_1);
}
#[test]
fn panic_precision() {
let a = PolyOverQ::from_str(&format!("1 {}", u64::MAX)).unwrap();
let _ = a.to_string_decimal(1);
}
}
#[cfg(test)]
mod test_to_string {
use super::PolyOverQ;
use std::str::FromStr;
#[test]
fn working_keeps_same_string() {
let cmp_str = "5 0 1 2/5 -3/2 1";
let cmp = PolyOverQ::from_str(cmp_str).unwrap();
assert_eq!(cmp_str, cmp.to_string());
}
#[test]
fn working_use_result_of_to_string_as_input() {
let cmp_str = "5 0 1 2/5 -3/2 1";
let cmp = PolyOverQ::from_str(cmp_str).unwrap();
let cmp_str_2 = cmp.to_string();
assert!(PolyOverQ::from_str(&cmp_str_2).is_ok());
}
#[test]
fn into_works_properly() {
let cmp = "2 6/7 2";
let poly = PolyOverQ::from_str(cmp).unwrap();
let string: String = poly.clone().into();
let borrowed_string: String = (&poly).into();
assert_eq!(cmp, string);
assert_eq!(cmp, borrowed_string);
}
}