dbc_rs/version/builder/
mod.rs

1use crate::{Result, Version};
2
3/// Builder for creating `Version` programmatically.
4///
5/// This builder allows you to construct version strings when building DBC files
6/// programmatically by specifying a complete version string.
7///
8/// # Examples
9///
10/// ```rust,no_run
11/// use dbc_rs::VersionBuilder;
12///
13/// // Direct version string
14/// let version = VersionBuilder::new().version("1.0").build()?;
15/// assert_eq!(version.as_str(), "1.0");
16///
17/// // Semantic versioning (as a string)
18/// let version2 = VersionBuilder::new()
19///     .version("1.2.3")
20///     .build()?;
21/// assert_eq!(version2.as_str(), "1.2.3");
22/// # Ok::<(), dbc_rs::Error>(())
23/// ```
24///
25/// # Feature Requirements
26///
27/// This builder requires the `std` feature to be enabled.
28#[derive(Debug)]
29pub struct VersionBuilder {
30    version: Option<String>,
31}
32
33impl VersionBuilder {
34    /// Creates a new `VersionBuilder` with no version set.
35    ///
36    /// # Examples
37    ///
38    /// ```rust,no_run
39    /// use dbc_rs::VersionBuilder;
40    ///
41    /// let builder = VersionBuilder::new();
42    /// // Must set version before building
43    /// let version = builder.version("1.0").build()?;
44    /// # Ok::<(), dbc_rs::Error>(())
45    /// ```
46    pub fn new() -> Self {
47        Self { version: None }
48    }
49
50    /// Sets the complete version string.
51    ///
52    /// # Arguments
53    ///
54    /// * `version` - The complete version string (e.g., "1.0", "1.2.3", "1.0-beta")
55    ///
56    /// # Examples
57    ///
58    /// ```rust,no_run
59    /// use dbc_rs::VersionBuilder;
60    ///
61    /// let version = VersionBuilder::new()
62    ///     .version("1.2.3")
63    ///     .build()?;
64    /// assert_eq!(version.as_str(), "1.2.3");
65    /// # Ok::<(), dbc_rs::Error>(())
66    /// ```
67    #[must_use = "builder method returns modified builder"]
68    pub fn version(mut self, version: impl AsRef<str>) -> Self {
69        self.version = Some(version.as_ref().to_string());
70        self
71    }
72
73    /// Builds the `Version` from the builder configuration.
74    ///
75    /// This validates that a version has been set and constructs a `Version` instance
76    /// with static lifetime.
77    ///
78    /// # Returns
79    ///
80    /// Returns `Ok(Version)` if successful, or `Err(Error::Version)` if:
81    /// - No version has been set (empty version)
82    ///
83    /// # Examples
84    ///
85    /// ```rust,no_run
86    /// use dbc_rs::VersionBuilder;
87    ///
88    /// // Build with version string
89    /// let version = VersionBuilder::new()
90    ///     .version("1.0")
91    ///     .build()?;
92    /// assert_eq!(version.as_str(), "1.0");
93    /// # Ok::<(), dbc_rs::Error>(())
94    /// ```
95    ///
96    /// # Errors
97    ///
98    /// ```rust,no_run
99    /// use dbc_rs::VersionBuilder;
100    ///
101    /// // Missing version
102    /// let result = VersionBuilder::new().build();
103    /// assert!(result.is_err());
104    ///
105    /// // Empty string is allowed
106    /// let version = VersionBuilder::new().version("").build()?;
107    /// assert_eq!(version.as_str(), "");
108    /// # Ok::<(), dbc_rs::Error>(())
109    /// ```
110    pub fn build(self) -> Result<Version> {
111        match self.version {
112            Some(v) => Ok(Version::new(v.into())),
113            None => Ok(Version::new("".to_string().into())),
114        }
115
116        // Use Cow::Owned for owned strings (no leak needed)
117    }
118}
119
120impl Default for VersionBuilder {
121    fn default() -> Self {
122        Self::new()
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::VersionBuilder;
129
130    #[test]
131    fn test_version_builder_version_string() {
132        let version = VersionBuilder::new().version("1.0").build().unwrap();
133        assert_eq!(version.as_str(), "1.0");
134    }
135
136    #[test]
137    fn test_version_builder_missing_version() {
138        let result = VersionBuilder::new().build();
139        assert!(result.is_ok());
140    }
141
142    #[test]
143    fn test_version_builder_with_special_chars() {
144        let version = VersionBuilder::new().version("1.0-beta").build().unwrap();
145        assert_eq!(version.as_str(), "1.0-beta");
146    }
147
148    #[test]
149    fn test_version_builder_empty_string() {
150        let version = VersionBuilder::new().version("").build().unwrap();
151        assert_eq!(version.as_str(), "");
152    }
153
154    #[test]
155    fn test_version_builder_long_version() {
156        let long_version = "1.2.3.4.5.6.7.8.9.10";
157        let version = VersionBuilder::new().version(long_version).build().unwrap();
158        assert_eq!(version.as_str(), long_version);
159    }
160}