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}