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}