dbc_rs/version/
version_builder.rs

1use crate::{Error, Result, Version, error::messages};
2
3#[derive(Debug, Default)]
4pub struct VersionBuilder {
5    version: Option<String>,
6}
7
8impl VersionBuilder {
9    pub fn new() -> Self {
10        Self::default()
11    }
12
13    #[must_use]
14    pub fn version(mut self, version: &str) -> Self {
15        self.version = Some(version.to_string());
16        self
17    }
18
19    #[must_use]
20    pub fn major(mut self, major: u8) -> Self {
21        self.version = Some(major.to_string());
22        self
23    }
24
25    #[must_use]
26    pub fn minor(mut self, minor: u8) -> Self {
27        if let Some(ref mut v) = self.version {
28            *v = format!("{}.{}", v, minor);
29        } else {
30            // If major wasn't called, treat this as just the version string
31            self.version = Some(minor.to_string());
32        }
33        self
34    }
35
36    #[must_use]
37    pub fn patch(mut self, patch: u8) -> Self {
38        if let Some(ref mut v) = self.version {
39            *v = format!("{}.{}", v, patch);
40        } else {
41            // If major/minor weren't called, treat this as just the version string
42            self.version = Some(patch.to_string());
43        }
44        self
45    }
46
47    pub fn build(self) -> Result<Version<'static>> {
48        let version = self
49            .version
50            .ok_or_else(|| Error::Version(messages::VERSION_EMPTY.to_string()))?;
51
52        // Convert owned String to static reference by leaking Box<str>
53        let boxed: Box<str> = version.into_boxed_str();
54        let static_ref: &'static str = Box::leak(boxed);
55        Ok(Version::new(static_ref))
56    }
57}
58
59#[cfg(all(test, feature = "alloc"))]
60mod tests {
61    use super::VersionBuilder;
62    use crate::error::lang;
63
64    #[test]
65    fn test_version_builder_version_string() {
66        let version = VersionBuilder::new().version("1.0").build().unwrap();
67        assert_eq!(version.to_string(), "1.0");
68    }
69
70    #[test]
71    fn test_version_builder_major_only() {
72        let version = VersionBuilder::new().major(1).build().unwrap();
73        assert_eq!(version.to_string(), "1");
74    }
75
76    #[test]
77    fn test_version_builder_major_minor() {
78        let version = VersionBuilder::new().major(1).minor(0).build().unwrap();
79        assert_eq!(version.to_string(), "1.0");
80    }
81
82    #[test]
83    fn test_version_builder_full() {
84        let version = VersionBuilder::new().major(1).minor(2).patch(3).build().unwrap();
85        assert_eq!(version.to_string(), "1.2.3");
86    }
87
88    #[test]
89    #[cfg(feature = "alloc")]
90    fn test_version_builder_missing_version() {
91        use crate::Error;
92
93        let result = VersionBuilder::new().build();
94        assert!(result.is_err());
95        match result.unwrap_err() {
96            Error::Version(msg) => assert!(msg.contains(lang::VERSION_EMPTY)),
97            _ => panic!("Expected Version error"),
98        }
99    }
100
101    #[test]
102    fn test_version_builder_with_special_chars() {
103        let version = VersionBuilder::new().version("1.0-beta").build().unwrap();
104        assert_eq!(version.to_string(), "1.0-beta");
105    }
106}