1use serde::{de::Visitor, Deserialize, Serialize};
2
3use super::{dependency::Dependency, version::Version, FactorioVersion};
4
5impl Serialize for Version {
6 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
7 where
8 S: serde::Serializer,
9 {
10 let str = format!("{}.{}.{}", self.major, self.minor, self.patch);
11 serializer.serialize_str(str.as_str())
12 }
13}
14
15impl<'de> Deserialize<'de> for Version {
16 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
17 where
18 D: serde::Deserializer<'de>,
19 {
20 struct VersionVisitor;
21
22 impl<'de> Visitor<'de> for VersionVisitor {
23 type Value = Version;
24
25 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
26 formatter.write_str("a valid version string ('major.minor.patch')")
27 }
28
29 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
30 where
31 E: serde::de::Error,
32 {
33 Version::parse(v).map_err(|_| serde::de::Error::custom("invalid version"))
34 }
35 }
36
37 deserializer.deserialize_str(VersionVisitor)
38 }
39}
40
41impl Serialize for FactorioVersion {
42 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43 where
44 S: serde::Serializer,
45 {
46 let str = if let Some(patch) = self.patch {
47 format!("{}.{}.{}", self.major, self.minor, patch)
48 } else {
49 format!("{}.{}", self.major, self.minor)
50 };
51
52 serializer.serialize_str(str.as_str())
53 }
54}
55
56impl<'de> Deserialize<'de> for FactorioVersion {
57 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
58 where
59 D: serde::Deserializer<'de>,
60 {
61 struct FactorioVersionVisitor;
62
63 impl<'de> Visitor<'de> for FactorioVersionVisitor {
64 type Value = FactorioVersion;
65
66 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
67 formatter.write_str("a valid Factorio version string ('major.minor')")
68 }
69
70 fn visit_none<E>(self) -> Result<Self::Value, E>
71 where
72 E: serde::de::Error,
73 {
74 Ok(FactorioVersion::default())
75 }
76
77 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
78 where
79 E: serde::de::Error,
80 {
81 FactorioVersion::parse(v)
82 .map_err(|_| serde::de::Error::custom("invalid Factorio version"))
83 }
84 }
85
86 deserializer.deserialize_str(FactorioVersionVisitor)
87 }
88}
89
90impl Serialize for Dependency {
91 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92 where
93 S: serde::Serializer,
94 {
95 serializer.collect_str(self)
96 }
97}
98
99impl<'de> Deserialize<'de> for Dependency {
100 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
101 where
102 D: serde::Deserializer<'de>,
103 {
104 struct DependencyVisitor;
105
106 impl<'de> Visitor<'de> for DependencyVisitor {
107 type Value = Dependency;
108
109 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
110 formatter.write_str("a valid dependency string ('[mode] name [version-req]')")
111 }
112
113 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
114 where
115 E: serde::de::Error,
116 {
117 Dependency::parse(v).map_err(|_| serde::de::Error::custom("invalid dependency"))
118 }
119 }
120
121 deserializer.deserialize_str(DependencyVisitor)
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 use crate::version::VersionReq;
128
129 use super::*;
130
131 #[test]
132 fn test_serialize_version() {
133 let version = Version::parse("1.2.3").unwrap();
134 let serialized = serde_json::to_string(&version).unwrap();
135 assert_eq!(serialized, "\"1.2.3\"");
136 }
137
138 #[test]
139 fn test_deserialize_version() {
140 let version = Version::parse("1.2.3").unwrap();
141 let deserialized: Version = serde_json::from_str("\"1.2.3\"").unwrap();
142 assert_eq!(deserialized, version);
143 }
144
145 #[test]
146 fn test_serialize_factorio_version() {
147 let version = FactorioVersion::parse("1.2").unwrap();
148 let serialized = serde_json::to_string(&version).unwrap();
149 assert_eq!(serialized, "\"1.2\"");
150 }
151
152 #[test]
153 fn test_deserialize_factorio_version() {
154 let version = FactorioVersion::parse("1.2").unwrap();
155 let deserialized: FactorioVersion = serde_json::from_str("\"1.2\"").unwrap();
156 assert_eq!(deserialized, version);
157 }
158
159 #[test]
160 fn test_serialize_dependency() {
161 let dependency =
162 Dependency::optional("facti", VersionReq::parse(">= 4.2.0").unwrap(), false);
163 let serialized = serde_json::to_string(&dependency).unwrap();
164 assert_eq!(serialized, "\"? facti >= 4.2.0\"");
165 }
166
167 #[test]
168 fn test_deserialize_dependency() {
169 let dependency = Dependency::optional("facti", VersionReq::parse("< 1.0.0").unwrap(), true);
170 let deserialized: Dependency = serde_json::from_str("\"(?) facti < 1.0.0\"").unwrap();
171 assert_eq!(deserialized, dependency);
172 }
173}