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}