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