Skip to main content

tanzim_validate/
semver.rs

1use crate::error::{Error, ErrorKind};
2use crate::{Meta, Validator};
3use tanzim_value::{Value, ValueType};
4
5/// (`semver` feature) Accepts a semantic version string such as `1.4.2` or `2.0.0-rc.1`.
6#[derive(Debug, Clone, Default)]
7pub struct Semver {
8    meta: Meta,
9}
10
11impl Semver {
12    pub fn new() -> Self {
13        Self {
14            meta: Meta::default(),
15        }
16    }
17
18    /// Attach human-facing metadata (name, description, examples, default, output conversion).
19    pub fn with_meta(mut self, meta: Meta) -> Self {
20        self.meta = meta;
21        self
22    }
23}
24
25impl Validator for Semver {
26    fn meta(&self) -> &Meta {
27        &self.meta
28    }
29
30    fn meta_mut(&mut self) -> &mut Meta {
31        &mut self.meta
32    }
33
34    fn check(&self, value: &mut Value) -> Result<(), Error> {
35        let text = match value {
36            Value::String(text) => text,
37            other => {
38                return Err(Error::new(ErrorKind::Type {
39                    expected: ValueType::String,
40                    found: other.type_name(),
41                }));
42            }
43        };
44        match text.parse::<semver::Version>() {
45            Ok(_) => Ok(()),
46            Err(_) => Err(Error::new(ErrorKind::Format {
47                expected: "semantic version",
48            })),
49        }
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn accepts_and_rejects() {
59        assert!(
60            Semver::new()
61                .validate(&mut Value::String("1.2.3".into()))
62                .is_ok()
63        );
64        assert!(
65            Semver::new()
66                .validate(&mut Value::String("1.2".into()))
67                .is_err()
68        );
69    }
70}