darkfi_serial/types/
semver.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 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, ErrorKind, 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::new(ErrorKind::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::new(ErrorKind::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(_) => {
89                Err(Error::new(ErrorKind::Other, "Failed deserializing semver::BuildMetadata"))
90            }
91        }
92    }
93}
94
95#[cfg(feature = "async")]
96#[async_trait]
97impl AsyncDecodable for semver::BuildMetadata {
98    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
99        let s: String = AsyncDecodable::decode_async(d).await?;
100
101        match Self::new(&s) {
102            Ok(v) => Ok(v),
103            Err(_) => {
104                Err(Error::new(ErrorKind::Other, "Failed deserializing semver::BuildMetadata"))
105            }
106        }
107    }
108}
109
110impl Encodable for semver::Version {
111    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
112        let mut len = 0;
113        len += self.major.encode(s)?;
114        len += self.minor.encode(s)?;
115        len += self.patch.encode(s)?;
116        len += self.pre.encode(s)?;
117        len += self.build.encode(s)?;
118        Ok(len)
119    }
120}
121
122#[cfg(feature = "async")]
123#[async_trait]
124impl AsyncEncodable for semver::Version {
125    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
126        let mut len = 0;
127        len += self.major.encode_async(s).await?;
128        len += self.minor.encode_async(s).await?;
129        len += self.patch.encode_async(s).await?;
130        len += self.pre.encode_async(s).await?;
131        len += self.build.encode_async(s).await?;
132        Ok(len)
133    }
134}
135
136impl Decodable for semver::Version {
137    fn decode<D: Read>(d: &mut D) -> Result<Self> {
138        let major: u64 = Decodable::decode(d)?;
139        let minor: u64 = Decodable::decode(d)?;
140        let patch: u64 = Decodable::decode(d)?;
141        let pre: semver::Prerelease = Decodable::decode(d)?;
142        let build: semver::BuildMetadata = Decodable::decode(d)?;
143        Ok(Self { major, minor, patch, pre, build })
144    }
145}
146#[cfg(feature = "async")]
147#[async_trait]
148impl AsyncDecodable for semver::Version {
149    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
150        let major: u64 = AsyncDecodable::decode_async(d).await?;
151        let minor: u64 = AsyncDecodable::decode_async(d).await?;
152        let patch: u64 = AsyncDecodable::decode_async(d).await?;
153        let pre: semver::Prerelease = AsyncDecodable::decode_async(d).await?;
154        let build: semver::BuildMetadata = AsyncDecodable::decode_async(d).await?;
155        Ok(Self { major, minor, patch, pre, build })
156    }
157}
158
159#[cfg(test)]
160mod tests {
161    use crate::{deserialize, serialize};
162
163    #[test]
164    fn serialize_deserialize_semver() {
165        let versions = vec!["1.12.0", "1.21.3-beta", "2.0.0-rc.1"];
166
167        for version in versions {
168            let original = semver::Version::parse(version).unwrap();
169            let serialized = serialize(&original);
170            let deserialized = deserialize(&serialized).unwrap();
171            assert_eq!(original, deserialized);
172        }
173    }
174}