qfall_math/integer/poly_over_z/to_string.rs
1// Copyright © 2023 Marcel Luca Schmidt, Marvin Beckmann
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module contains all options to convert a polynomial of type
10//! [`PolyOverZ`] into a [`String`].
11//!
12//! This includes the [`Display`](std::fmt::Display) trait.
13
14use super::PolyOverZ;
15use crate::macros::for_others::implement_for_owned;
16use core::fmt;
17use flint_sys::fmpz_poly::fmpz_poly_get_str;
18use std::ffi::CStr;
19
20impl From<&PolyOverZ> for String {
21 /// Converts a [`PolyOverZ`] into its [`String`] representation.
22 ///
23 /// Parameters:
24 /// - `value`: specifies the polynomial that will be represented as a [`String`]
25 ///
26 /// Returns a [`String`] of the form `"[#number of coefficients]⌴⌴[0th coefficient]⌴[1st coefficient]⌴..."`.
27 ///
28 /// # Examples
29 /// ```
30 /// use qfall_math::integer::PolyOverZ;
31 /// use std::str::FromStr;
32 /// let poly = PolyOverZ::from_str("2 6 1").unwrap();
33 ///
34 /// let string: String = poly.into();
35 /// ```
36 fn from(value: &PolyOverZ) -> Self {
37 value.to_string()
38 }
39}
40
41implement_for_owned!(PolyOverZ, String, From);
42
43impl fmt::Display for PolyOverZ {
44 /// Allows to convert a polynomial of type [`PolyOverZ`] into a [`String`].
45 ///
46 /// # Examples
47 /// ```
48 /// use qfall_math::integer::PolyOverZ;
49 /// use std::str::FromStr;
50 /// use core::fmt;
51 ///
52 /// let poly = PolyOverZ::from_str("4 0 1 2 3").unwrap();
53 /// println!("{poly}");
54 /// ```
55 ///
56 /// ```
57 /// use qfall_math::integer::PolyOverZ;
58 /// use std::str::FromStr;
59 ///
60 /// let poly = PolyOverZ::from_str("4 0 1 2 3").unwrap();
61 /// let poly_string = poly.to_string();
62 /// ```
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 let c_str_ptr = unsafe { fmpz_poly_get_str(&self.poly) };
65 let return_str = unsafe { CStr::from_ptr(c_str_ptr).to_str().unwrap().to_owned() };
66 // free the space allocated by the pointer
67 unsafe { libc::free(c_str_ptr as *mut libc::c_void) };
68 write!(f, "{return_str}")
69 }
70}
71
72#[cfg(test)]
73mod test_to_string {
74 use super::PolyOverZ;
75 use std::str::FromStr;
76
77 /// Tests whether a polynomial that is created using a string, returns the
78 /// same string, when it is converted back to a string
79 #[test]
80 fn working_keeps_same_string() {
81 let cmp_str = "3 1 2 -3";
82 let cmp = PolyOverZ::from_str(cmp_str).unwrap();
83
84 assert_eq!(cmp_str, cmp.to_string());
85 }
86
87 /// Tests whether a polynomial that is created using a string, returns a
88 /// string that can be used to create a polynomial
89 #[test]
90 fn working_use_result_of_to_string_as_input() {
91 let cmp_str = "3 1 2 -3";
92 let cmp = PolyOverZ::from_str(cmp_str).unwrap();
93
94 let cmp_str_2 = cmp.to_string();
95
96 assert!(PolyOverZ::from_str(&cmp_str_2).is_ok());
97 }
98
99 /// Tests whether large entries are correctly converted using to_string
100 #[test]
101 fn large_entries() {
102 let cmp_str = format!("3 1 {} -{}", u64::MAX, u64::MAX);
103 let cmp = PolyOverZ::from_str(&cmp_str).unwrap();
104
105 let cmp_str_2 = cmp.to_string();
106
107 assert!(PolyOverZ::from_str(&cmp_str_2).is_ok());
108 }
109
110 /// Ensures that the `Into<String>` trait works properly
111 #[test]
112 fn into_works_properly() {
113 let cmp = "2 6 1";
114 let poly = PolyOverZ::from_str(cmp).unwrap();
115
116 let string: String = poly.clone().into();
117 let borrowed_string: String = (&poly).into();
118
119 assert_eq!(cmp, string);
120 assert_eq!(cmp, borrowed_string);
121 }
122}