qfall_math/integer_mod_q/poly_over_zq/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 modulus of type
10//! [`PolyOverZq`] into a [`String`].
11//!
12//! This includes the [`Display`](std::fmt::Display) trait.
13
14use super::PolyOverZq;
15use crate::{integer::PolyOverZ, macros::for_others::implement_for_owned};
16use flint_sys::fmpz_mod_poly::fmpz_mod_poly_get_fmpz_poly;
17use std::fmt;
18
19impl From<&PolyOverZq> for String {
20 /// Converts a [`PolyOverZq`] into its [`String`] representation.
21 ///
22 /// Parameters:
23 /// - `value`: specifies the polynommial that will be represented as a [`String`]
24 ///
25 /// Returns a [`String`] of the form `"[#number of coefficients]⌴⌴[0th coefficient]⌴[1st coefficient]⌴...⌴mod⌴[q]"`.
26 ///
27 /// # Examples
28 /// ```
29 /// use qfall_math::integer_mod_q::PolyOverZq;
30 /// use std::str::FromStr;
31 /// let poly = PolyOverZq::from_str("2 2 1 mod 3").unwrap();
32 ///
33 /// let string: String = poly.into();
34 /// ```
35 fn from(value: &PolyOverZq) -> Self {
36 value.to_string()
37 }
38}
39
40implement_for_owned!(PolyOverZq, String, From);
41
42impl fmt::Display for PolyOverZq {
43 /// Allows to convert a [`PolyOverZq`] into a [`String`].
44 ///
45 /// # Examples
46 /// ```
47 /// use qfall_math::integer_mod_q::PolyOverZq;
48 /// use std::str::FromStr;
49 /// use core::fmt;
50 ///
51 /// let poly = PolyOverZq::from_str("4 0 1 2 3 mod 5").unwrap();
52 /// println!("{poly}");
53 /// ```
54 ///
55 /// ```
56 /// use qfall_math::integer_mod_q::PolyOverZq;
57 /// use std::str::FromStr;
58 ///
59 /// let poly = PolyOverZq::from_str("4 0 1 2 3 mod 5").unwrap();
60 /// let poly_string = poly.to_string();
61 /// ```
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 // there is no dedicated method to create a string from a fmpz_mod_poly
64 // hence we convert it to a fmpz_poly first to use the dedicated method
65
66 let mut poly_over_z = PolyOverZ::default();
67 unsafe {
68 fmpz_mod_poly_get_fmpz_poly(
69 &mut poly_over_z.poly,
70 &self.poly,
71 self.modulus.get_fmpz_mod_ctx_struct(),
72 )
73 };
74 write!(f, "{poly_over_z} mod {}", self.modulus)
75 }
76}
77
78#[cfg(test)]
79mod test_to_string {
80 use super::PolyOverZq;
81 use std::str::FromStr;
82
83 /// Tests whether a polynomial that is created using a string, returns the
84 /// same string, when it is converted back to a string
85 #[test]
86 fn working_keeps_same_string() {
87 let cmp_str = "3 1 2 2 mod 5";
88 let cmp = PolyOverZq::from_str(cmp_str).unwrap();
89
90 assert_eq!(cmp_str, cmp.to_string());
91 }
92
93 /// Tests whether a polynomial that is created using a string, returns a
94 /// string that can be used to create a polynomial
95 #[test]
96 fn working_use_result_of_to_string_as_input() {
97 let cmp_str = "3 1 2 2 mod 5";
98 let cmp = PolyOverZq::from_str(cmp_str).unwrap();
99
100 let cmp_str_2 = cmp.to_string();
101
102 assert!(PolyOverZq::from_str(&cmp_str_2).is_ok());
103 }
104
105 /// Test applied modulus if initialized with negative values
106 #[test]
107 fn initialized_neg() {
108 let cmp_str = "3 -1 -2 -3 mod 5";
109 let cmp = PolyOverZq::from_str(cmp_str).unwrap();
110
111 assert_eq!("3 4 3 2 mod 5", cmp.to_string());
112 }
113
114 /// Tests that large entries and large moduli work with to_string()
115 #[test]
116 fn large_entries_modulus() {
117 let cmp_str = format!("3 1 2 {} mod 1{}", u64::MAX, u64::MAX);
118 let cmp = PolyOverZq::from_str(&cmp_str).unwrap();
119
120 assert_eq!(cmp_str, cmp.to_string());
121 }
122
123 /// Ensures that the `Into<String>` trait works properly
124 #[test]
125 fn into_works_properly() {
126 let cmp = "2 2 1 mod 3";
127 let poly = PolyOverZq::from_str(cmp).unwrap();
128
129 let string: String = poly.clone().into();
130 let borrowed_string: String = (&poly).into();
131
132 assert_eq!(cmp, string);
133 assert_eq!(cmp, borrowed_string);
134 }
135}