1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// first thing to do is a getter to simplify code

use super::gen_coordinate::CoordinateBasics;
use super::unsafe_coordinate::UnsafeCoordinate;
use super::safe_coordinate::SafeCoordinate;

#[doc = "Esta es la enumeración `ECoordinate`."]

pub enum ECoordinate {
    /// Una variante que representa una coordenada segura.
    Safe(SafeCoordinate),
    /// Una variante que representa una coordenada insegura.
    Unsafe(UnsafeCoordinate),
}



impl ECoordinate {
    
    fn get_x(&self) -> Option<f32> {
        match self {
            ECoordinate::Safe(coord) => Some(coord.get_x()),
            ECoordinate::Unsafe(coord) => Some(coord.get_x()),
            _ => None,
        }
    }

    fn get_y(&self) -> Option<f32> {
        match self {
            ECoordinate::Safe(coord) => Some(coord.get_y()),
            ECoordinate::Unsafe(coord) => Some(coord.get_y()),
            _ => None,
        }
    }
    

    
    ///The funciton equiv:
///It compares two ECoordinates to see if they are equivalent. Two ECoordinates are 
/// equivalent if they have the same values for x and y. If either value is None, 
/// then they are considered not equivalent.
/// 
/// # Parameters
///
/// * `altcoordinate: A reference to another ECoordinate to compare to self.
///
/// # Returns
///
/// `true if self and altcoordinate are equivalent, false otherwise.
///
/// # Examples
///
/// /*```
/// let coord1 = ECoordinate::Safe(SafeCoordinate { x: 1.0, y: 2.0 });
/// let coord2 = ECoordinate::Safe(SafeCoordinate { x: 1.0, y: 2.0 });
/// assert!(coord1.equiv(&coord2));
///
/// let coord3 = ECoordinate::Safe(SafeCoordinate { x: 1.0, y: 2.0 });
/// let coord4 = ECoordinate::Safe(SafeCoordinate { x: 2.0, y: 2.0 });
/// assert!(!coord3.equiv(&coord4));
/// ```*/
/// 
    

fn equiv(&self, altcoordinate: &Self) -> bool {
        let x = match (self.get_x(), altcoordinate.get_x()) {
            (Some(self_x), Some(alt_x)) => self_x / alt_x,
            _ => 0.0,
        };
        let y = match (self.get_y(), altcoordinate.get_y()) {
            (Some(self_y), Some(alt_y)) => self_y / alt_y,
            _ => 0.0,
        };
        x == y
    }
    /// returns the distance between the two coordinates
    /// 
    fn distancia(&self, altcoordinate: &Self) -> f32 {
        match (self.get_x(), self.get_y(), altcoordinate.get_x(), altcoordinate.get_y()) {
            (Some(x1), Some(y1), Some(x2), Some(y2)) => {
                let dif_x = x1 - x2;
                let dif_y = y1 - y2;
                (dif_x.powi(2) + dif_y.powi(2)).sqrt()
            },
            _ => 0.0,
        }
    }

    fn equal(&self, coord2: &Self) -> bool {
        match (self.get_x(), self.get_y(), coord2.get_x(), coord2.get_y()) {
            (Some(x1), Some(y1), Some(x2), Some(y2)) => x1 == x2 && y1 == y2,
            _ => false,
        }
    }
    
    
    // En el futuro esto se puede extender de la forma:
    //match self {
    //eCoordinate::Safe(safe_coord) => {
        // do something with the safe coordinate
    //}
    //eCoordinate::Unsafe(unsafe_coord) => {
        // do something with the unsafe coordinate
    //}
    //
    //
    

}



#[test]
fn test_safe_coordinate_operations() {
    let var_x1:f32=14.0;
    let var_y1:f32=20.0;
    let var_x2:f32=-13.0;
    let var_y2:f32=12.0;
    //En los tests no se ponen los tipos
    let coord1 : ECoordinate=  ECoordinate::Safe(SafeCoordinate::new(var_x1,var_y1));
    let coord2 :ECoordinate=ECoordinate::Safe(SafeCoordinate::new(var_x2,var_y2));
    let distancia: f32=coord1.distancia(&coord2);
    let ne:bool=coord1.equal(&coord2);
    let eq:bool=coord1.equal(&coord1);
    let c_mod:bool=coord1.equiv(&coord2);
    let c_mod_reg:bool=coord1.equiv(&coord1);

    assert_eq!(28.160255, distancia);
    assert_eq!(false,ne);
    assert_eq!(true,eq);
    assert_eq!(false,c_mod);
    assert_eq!(true,c_mod_reg);
}

#[test]
fn test_unsafe_coordinate_operations() {
    let var_x1:f32=14.0;
    let var_y1:f32=20.0;
    let var_x2:f32=-13.0;
    let var_y2:f32=12.0;
    //En los tests no se ponen los tipos
    let coord1 : ECoordinate=  ECoordinate::Unsafe(UnsafeCoordinate::new(var_x1,var_y1));
    let coord2 :ECoordinate=ECoordinate::Unsafe(UnsafeCoordinate::new(var_x2,var_y2));
    let distancia: f32=coord1.distancia(&coord2);
    let ne:bool=coord1.equal(&coord2);
    let eq:bool=coord1.equal(&coord1);
    let c_mod:bool=coord1.equiv(&coord2);
    let c_mod_reg:bool=coord1.equiv(&coord1);

    assert_eq!(28.160255, distancia);
    assert_eq!(false,ne);
    assert_eq!(true,eq);
    assert_eq!(false,c_mod);
    assert_eq!(true,c_mod_reg);
}