1use crate::{Vector3, Vector3Coordinate};
2use thiserror::Error;
3
4impl<T: Vector3Coordinate> From<(T, T, T)> for Vector3<T> {
5 fn from(value: (T, T, T)) -> Self {
6 Self {
7 x: value.0,
8 y: value.1,
9 z: value.2,
10 }
11 }
12}
13
14impl<T: Vector3Coordinate> From<Vector3<T>> for (T, T, T) {
15 fn from(value: Vector3<T>) -> Self {
16 (value.x, value.y, value.z)
17 }
18}
19
20impl<T: Vector3Coordinate> From<[T; 3]> for Vector3<T> {
21 fn from(value: [T; 3]) -> Self {
22 let [x, y, z] = value;
23 Self { x, y, z }
24 }
25}
26
27#[cfg(feature = "std")]
28impl<T: Vector3Coordinate> From<Vector3<T>> for [T; 3] {
29 fn from(value: Vector3<T>) -> Self {
30 [value.x, value.y, value.z]
31 }
32}
33
34#[derive(Error, Debug)]
35pub enum ParseVector3Error {
36 #[error("failed to parse #{0}th component")]
37 StringParseComponentError(usize),
38 #[error("invalid format")]
39 InvalidStringFormat,
40 #[error("invalid vector length: expected 3, got {0}")]
41 InvalidVec(usize),
42}
43
44#[cfg(feature = "std")]
45impl<T: Vector3Coordinate> TryFrom<Vec<T>> for Vector3<T> {
46 type Error = ParseVector3Error;
47 fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
48 let array: [T; 3] = value
49 .try_into()
50 .map_err(|v: Vec<T>| ParseVector3Error::InvalidVec(v.len()))?;
51 Ok(Self::from(array))
52 }
53}
54
55#[cfg(feature = "std")]
56impl<T: Vector3Coordinate> TryFrom<std::collections::VecDeque<T>> for Vector3<T> {
57 type Error = ParseVector3Error;
58 fn try_from(mut value: std::collections::VecDeque<T>) -> Result<Self, Self::Error> {
59 let x = value
60 .pop_front()
61 .ok_or(ParseVector3Error::InvalidVec(value.len()))?;
62 let y = value
63 .pop_front()
64 .ok_or(ParseVector3Error::InvalidVec(value.len()))?;
65 let z = value
66 .pop_front()
67 .ok_or(ParseVector3Error::InvalidVec(value.len()))?;
68 Ok(Self::new(x, y, z))
69 }
70}
71
72impl<T> core::str::FromStr for Vector3<T>
73where
74 T: Vector3Coordinate + core::str::FromStr,
75{
76 type Err = ParseVector3Error;
77 fn from_str(s: &str) -> Result<Self, Self::Err> {
78 let Some(data) = s.strip_prefix("Vector3(") else {
79 return Err(ParseVector3Error::InvalidStringFormat);
80 };
81 let Some(data) = data.strip_suffix(")") else {
82 return Err(ParseVector3Error::InvalidStringFormat);
83 };
84
85 let mut components = data
86 .split(',')
87 .take(3)
88 .enumerate()
89 .flat_map(|(index, coord)| {
90 coord
91 .trim()
92 .parse::<T>()
93 .map_err(|_| ParseVector3Error::StringParseComponentError(index + 1))
94 });
95
96 let x = components
99 .next()
100 .ok_or(ParseVector3Error::StringParseComponentError(1))?;
101 let y = components
102 .next()
103 .ok_or(ParseVector3Error::StringParseComponentError(2))?;
104 let z = components
105 .next()
106 .ok_or(ParseVector3Error::StringParseComponentError(3))?;
107
108 Ok(Self::new(x, y, z))
109 }
110}
111
112#[cfg(test)]
113mod test {
114 use super::*;
115
116 #[test]
117 fn vec_string() {
118 let v1: Vector3<i32> = Vector3::new(1, 2, 3);
119 let v2: Vector3<i32> = String::from("Vector3( 1,2, 3)").parse().unwrap();
120 assert_eq!(v1, v2);
121 }
122
123 #[test]
124 fn vec_str() {
125 let v1 = Vector3::new(1, 2, 3);
126 let v2 = "Vector3(1, 2 ,3 )".parse().unwrap();
127 assert_eq!(v1, v2);
128 }
129
130 #[test]
131 fn vec_tuple() {
132 let v1 = Vector3::new(1, 2, 3);
133 let v2 = (1, 2, 3).into();
134 assert_eq!(v1, v2);
135 }
136
137 #[test]
138 fn vec_array() {
139 let v1 = Vector3::new(1, 2, 3);
140 let v2 = [1, 2, 3].into();
141 assert_eq!(v1, v2);
142 }
143
144 #[test]
145 fn vec_vec() {
146 let v1 = Vector3::new(1, 2, 3);
147 let v2 = vec![1, 2, 3].try_into().unwrap();
148 assert_eq!(v1, v2);
149 }
150
151 #[test]
152 fn vec_deq() {
153 let v1 = Vector3::new(1, 2, 3);
154 let v2 = std::collections::VecDeque::from([1, 2, 3])
155 .try_into()
156 .unwrap();
157 assert_eq!(v1, v2);
158 }
159}