use std::ops::{Add, Mul, Neg, Sub};
use crate::FieldElement;
pub trait ExpressionConvertible<T, V> {
fn try_to_expression<
E: Add<E, Output = E> + Sub<E, Output = E> + Mul<E, Output = E> + Neg<Output = E>,
>(
&self,
number_converter: &impl Fn(&T) -> E,
var_converter: &impl Fn(&V) -> E,
_try_to_number: &impl Fn(&E) -> Option<T>,
) -> Option<E> {
Some(self.to_expression(number_converter, var_converter))
}
fn to_expression<
E: Add<E, Output = E> + Sub<E, Output = E> + Mul<E, Output = E> + Neg<Output = E>,
>(
&self,
number_converter: &impl Fn(&T) -> E,
var_converter: &impl Fn(&V) -> E,
) -> E {
self.try_to_expression(number_converter, var_converter, &|_| unreachable!())
.unwrap()
}
}
impl<V, T: FieldElement> ExpressionConvertible<T, V> for T {
fn to_expression<
E: Add<E, Output = E> + Sub<E, Output = E> + Mul<E, Output = E> + Neg<Output = E>,
>(
&self,
number_converter: &impl Fn(&T) -> E,
_var_converter: &impl Fn(&V) -> E,
) -> E {
number_converter(self)
}
}