darkfi_serial/types/
semver.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2026 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19use std::io::{Error, Read, Result, Write};
20
21#[cfg(feature = "async")]
22use crate::{AsyncDecodable, AsyncEncodable};
23#[cfg(feature = "async")]
24use async_trait::async_trait;
25#[cfg(feature = "async")]
26use futures_lite::{AsyncRead, AsyncWrite};
27
28use crate::{Decodable, Encodable};
29
30impl Encodable for semver::Prerelease {
31    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
32        self.as_str().encode(s)
33    }
34}
35
36#[cfg(feature = "async")]
37#[async_trait]
38impl AsyncEncodable for semver::Prerelease {
39    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
40        self.as_str().encode_async(s).await
41    }
42}
43
44impl Decodable for semver::Prerelease {
45    fn decode<D: Read>(d: &mut D) -> Result<Self> {
46        let s: String = Decodable::decode(d)?;
47
48        match Self::new(&s) {
49            Ok(v) => Ok(v),
50            Err(_) => Err(Error::other("Failed deserializing semver::Prerelase")),
51        }
52    }
53}
54
55#[cfg(feature = "async")]
56#[async_trait]
57impl AsyncDecodable for semver::Prerelease {
58    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
59        let s: String = AsyncDecodable::decode_async(d).await?;
60
61        match Self::new(&s) {
62            Ok(v) => Ok(v),
63            Err(_) => Err(Error::other("Failed deserializing semver::Prerelease")),
64        }
65    }
66}
67
68impl Encodable for semver::BuildMetadata {
69    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
70        self.as_str().encode(s)
71    }
72}
73
74#[cfg(feature = "async")]
75#[async_trait]
76impl AsyncEncodable for semver::BuildMetadata {
77    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
78        self.as_str().encode_async(s).await
79    }
80}
81
82impl Decodable for semver::BuildMetadata {
83    fn decode<D: Read>(d: &mut D) -> Result<Self> {
84        let s: String = Decodable::decode(d)?;
85
86        match Self::new(&s) {
87            Ok(v) => Ok(v),
88            Err(_) => Err(Error::other("Failed deserializing semver::BuildMetadata")),
89        }
90    }
91}
92
93#[cfg(feature = "async")]
94#[async_trait]
95impl AsyncDecodable for semver::BuildMetadata {
96    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
97        let s: String = AsyncDecodable::decode_async(d).await?;
98
99        match Self::new(&s) {
100            Ok(v) => Ok(v),
101            Err(_) => Err(Error::other("Failed deserializing semver::BuildMetadata")),
102        }
103    }
104}
105
106impl Encodable for semver::Version {
107    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
108        let mut len = 0;
109        len += self.major.encode(s)?;
110        len += self.minor.encode(s)?;
111        len += self.patch.encode(s)?;
112        len += self.pre.encode(s)?;
113        len += self.build.encode(s)?;
114        Ok(len)
115    }
116}
117
118#[cfg(feature = "async")]
119#[async_trait]
120impl AsyncEncodable for semver::Version {
121    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
122        let mut len = 0;
123        len += self.major.encode_async(s).await?;
124        len += self.minor.encode_async(s).await?;
125        len += self.patch.encode_async(s).await?;
126        len += self.pre.encode_async(s).await?;
127        len += self.build.encode_async(s).await?;
128        Ok(len)
129    }
130}
131
132impl Decodable for semver::Version {
133    fn decode<D: Read>(d: &mut D) -> Result<Self> {
134        let major: u64 = Decodable::decode(d)?;
135        let minor: u64 = Decodable::decode(d)?;
136        let patch: u64 = Decodable::decode(d)?;
137        let pre: semver::Prerelease = Decodable::decode(d)?;
138        let build: semver::BuildMetadata = Decodable::decode(d)?;
139        Ok(Self { major, minor, patch, pre, build })
140    }
141}
142#[cfg(feature = "async")]
143#[async_trait]
144impl AsyncDecodable for semver::Version {
145    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
146        let major: u64 = AsyncDecodable::decode_async(d).await?;
147        let minor: u64 = AsyncDecodable::decode_async(d).await?;
148        let patch: u64 = AsyncDecodable::decode_async(d).await?;
149        let pre: semver::Prerelease = AsyncDecodable::decode_async(d).await?;
150        let build: semver::BuildMetadata = AsyncDecodable::decode_async(d).await?;
151        Ok(Self { major, minor, patch, pre, build })
152    }
153}
154
155#[cfg(test)]
156mod tests {
157    use crate::{deserialize, serialize};
158
159    #[test]
160    fn serialize_deserialize_semver() {
161        let versions = vec!["1.12.0", "1.21.3-beta", "2.0.0-rc.1"];
162
163        for version in versions {
164            let original = semver::Version::parse(version).unwrap();
165            let serialized = serialize(&original);
166            let deserialized = deserialize(&serialized).unwrap();
167            assert_eq!(original, deserialized);
168        }
169    }
170}