qfall_math/integer_mod_q/modulus_polynomial_ring_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 polynomial of type
10//! [`ModulusPolynomialRingZq`] into a [`String`].
11//!
12//! This includes the [`Display`] trait.
13
14use super::ModulusPolynomialRingZq;
15use crate::{
16 integer::{PolyOverZ, Z},
17 macros::for_others::implement_for_owned,
18};
19use flint_sys::{fmpz::fmpz_init_set, fmpz_mod_poly::fmpz_mod_poly_get_fmpz_poly};
20use std::fmt::Display;
21
22impl From<&ModulusPolynomialRingZq> for String {
23 /// Converts a [`ModulusPolynomialRingZq`] into its [`String`] representation.
24 ///
25 /// Parameters:
26 /// - `value`: specifies the polynomial that will be represented as a [`String`]
27 ///
28 /// Returns a [`String`] of the form `"[#number of coefficients]⌴⌴[0th coefficient]⌴[1st coefficient]⌴...⌴mod⌴[q]"`.
29 ///
30 /// # Examples
31 /// ```
32 /// use qfall_math::integer_mod_q::ModulusPolynomialRingZq;
33 /// use std::str::FromStr;
34 /// let modulus = ModulusPolynomialRingZq::from_str("2 2 1 mod 3").unwrap();
35 ///
36 /// let string: String = modulus.into();
37 /// ```
38 fn from(value: &ModulusPolynomialRingZq) -> Self {
39 value.to_string()
40 }
41}
42
43implement_for_owned!(ModulusPolynomialRingZq, String, From);
44
45impl Display for ModulusPolynomialRingZq {
46 /// Allows to convert a [`ModulusPolynomialRingZq`] into a [`String`].
47 ///
48 /// # Examples
49 /// ```
50 /// use qfall_math::integer_mod_q::ModulusPolynomialRingZq;
51 /// use std::str::FromStr;
52 ///
53 /// let poly = ModulusPolynomialRingZq::from_str("3 1 0 1 mod 17").unwrap();
54 /// println!("{poly}");
55 /// ```
56 ///
57 /// ```
58 /// use qfall_math::integer_mod_q::ModulusPolynomialRingZq;
59 /// use std::str::FromStr;
60 ///
61 /// let poly = ModulusPolynomialRingZq::from_str("3 1 0 1 mod 17").unwrap();
62 /// let poly_string = poly.to_string();
63 /// ```
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 // get the value of the modulus
66 let mut modulus = Z::default();
67 unsafe { fmpz_init_set(&mut modulus.value, &self.get_fq_ctx().ctxp[0].n[0]) };
68
69 // get the value of the polynomial
70 let mut poly = PolyOverZ::default();
71 unsafe {
72 fmpz_mod_poly_get_fmpz_poly(
73 &mut poly.poly,
74 &self.get_fq_ctx().modulus[0],
75 &self.get_fq_ctx().ctxp[0],
76 )
77 };
78
79 write!(f, "{poly} mod {modulus}")
80 }
81}
82
83/// most tests with specific values are covered in [`PolyOverZq`](crate::integer_mod_q::PolyOverZq)
84/// since the format is reused, we omit some tests
85#[cfg(test)]
86mod test_to_string {
87 use crate::integer_mod_q::ModulusPolynomialRingZq;
88 use std::str::FromStr;
89
90 /// Test whether a roundtrip works
91 #[test]
92 fn working_keeps_same_string() {
93 let cmp_str = "3 1 2 2 mod 5";
94 let cmp = ModulusPolynomialRingZq::from_str(cmp_str).unwrap();
95
96 assert_eq!(cmp_str, cmp.to_string());
97 }
98
99 /// Test whether a string returned from to_string can be used to construct a [`ModulusPolynomialRingZq`]
100 #[test]
101 fn working_use_result_of_to_string() {
102 let cmp_str = "3 1 2 2 mod 5";
103 let cmp = ModulusPolynomialRingZq::from_str(cmp_str).unwrap();
104 let str_1 = cmp.to_string();
105
106 assert!(ModulusPolynomialRingZq::from_str(&str_1).is_ok());
107 }
108
109 /// Ensures that the `Into<String>` trait works properly
110 #[test]
111 fn into_works_properly() {
112 let cmp = "2 2 1 mod 3";
113 let modulus = ModulusPolynomialRingZq::from_str(cmp).unwrap();
114
115 let string: String = modulus.clone().into();
116 let borrowed_string: String = (&modulus).into();
117
118 assert_eq!(cmp, string);
119 assert_eq!(cmp, borrowed_string);
120 }
121}