Hi all! I have doing too much this days, a lot of questions :3
I found something... curious, I was trying to do a design using generics, the idea is have a Point, which will build a Line, the key part is that the Line should be made using Point
or &mut Point
.
I has been testing to do this.... but I has not been able to be satisfied with my answer, my actual one is define Point as a Trait, and make the Line using the Trait as constrain, with this I have opened the door to define a NPoint struct, and from there I can implement the trait on NPoint
and &mut Point
.
The issue with this solution is the high amount of code duplication, after al, both implementations of Point on NPoint will be the same code....., I tried to look on Deref and played a little but I was not able to do it works to also make a new solution.
use std::marker::PhantomData;
pub trait Num:
num_traits::Num
+ Clone
+ num_traits::NumCast
+ PartialOrd
+ std::fmt::Debug
+ Default
+ num_traits::Float
+ TryFrom<f64, Error: std::fmt::Debug>
{
}
impl<
T: num_traits::Num
+ Clone
+ num_traits::NumCast
+ PartialOrd
+ std::fmt::Debug
+ Default
+ num_traits::Float
+ TryFrom<f64, Error: std::fmt::Debug>,
> Num for T
{
}
trait Point<const N: usize, T: Num> {
fn ref_coords(&self) -> &[T; N];
fn ref_mut_coords(&mut self) -> &mut [T; N];
fn coords(&self) -> [T; N];
}
struct NPoint<const N: usize, T: Num> {
coords: [T; N],
}
impl<const N: usize, T: Num> Point<N, T> for &mut NPoint<N, T> {
fn ref_coords(&self) -> &[T; N] {
&self.coords
}
fn ref_mut_coords(&mut self) -> &mut [T; N] {
&mut self.coords
}
fn coords(&self) -> [T; N] {
self.coords
}
}
impl<const N: usize, T: Num> Point<N, T> for NPoint<N, T> {
fn ref_coords(&self) -> &[T; N] {
&self.coords
}
fn ref_mut_coords(&mut self) -> &mut [T; N] {
&mut self.coords
}
fn coords(&self) -> [T; N] {
self.coords
}
}
struct NLine<const N: usize, T: Num, P: Point<N, T>> {
pub from: P,
pub to: P,
phantom: PhantomData<T>,
}
impl<const N: usize, T: Num, P: Point<N, T>> NLine<N, T, P> {
pub fn new(from: P, to: P) -> Self {
NLine {
from,
to,
phantom: PhantomData,
}
}
}
fn main() {
let mut point1 = NPoint { coords: [0.0] };
let mut point2 = NPoint { coords: [1.0] };
let line = NLine::new(point1, point2);
}
Someone have any idea how to improve this design to avoid duplicate so much code?
Note: The idea is repeat something very similar with Line to set of Lines, the input lines could be references or owned, also Points and Lines can have more functions.
Thx!