Skip to main content

sql_fun_core/extensions/
config_error.rs

1use std::path::{Path, PathBuf};
2
3use super::ExtensionVersion;
4
5/// error in extension configurations
6#[derive(thiserror::Error, Debug)]
7pub enum ExtensionConfigError {
8    /// invalid value for extension name
9    #[error("Invalid extension name {0}")]
10    InvalidExtensionName(String),
11
12    /// invalid value for extension version
13    #[error("Invalid extension version {0}")]
14    InvalidExtensionVersion(String),
15
16    /// IO error
17    #[error(transparent)]
18    Io(#[from] std::io::Error),
19
20    /// extension SQL not found
21    #[error("Extension {0} not found in {1}")]
22    ExtensionNotFound(String, PathBuf),
23
24    /// multiple extension version found, require specify one.
25    #[error("Extension {0} has multiple versions {1:?}, please specify one of version")]
26    MultipleExtensionVersion(String, Vec<String>, PathBuf),
27
28    /// Extension SQL file not existing on path
29    #[error("Extension {0}@{1} sql not exist: {2}")]
30    ExtensionSqlNotExist(String, ExtensionVersion, PathBuf),
31}
32
33impl ExtensionConfigError {
34    /// raise `InvalidExtensionName`
35    ///
36    /// # Errors
37    ///
38    /// Always returns [`ExtensionConfigError::InvalidExtensionName`].
39    pub fn invalid_extension_name<T>(name: &str) -> Result<T, Self> {
40        Err(Self::InvalidExtensionName(name.to_string()))
41    }
42
43    /// raise `InvalidExtensionVersion`
44    ///
45    /// # Errors
46    ///
47    /// Always returns [`ExtensionConfigError::InvalidExtensionVersion`].
48    pub fn invalid_extension_version<T>(version: &str) -> Result<T, Self> {
49        Err(Self::InvalidExtensionVersion(version.to_string()))
50    }
51
52    /// raise `ExtensionNotFound`
53    ///
54    /// # Errors
55    ///
56    /// Always returns [`ExtensionConfigError::ExtensionNotFound`].
57    pub fn extension_not_found<T, P: AsRef<Path>>(name: &str, base_path: P) -> Result<T, Self> {
58        Err(Self::ExtensionNotFound(
59            name.to_string(),
60            base_path.as_ref().to_path_buf(),
61        ))
62    }
63
64    /// raise `MultipleExtensionVersion`
65    ///
66    /// # Errors
67    ///
68    /// Always returns [`ExtensionConfigError::MultipleExtensionVersion`].
69    pub fn multiple_extension_version<T, P: AsRef<Path>>(
70        name: &str,
71        base_path: P,
72        versions: &[String],
73    ) -> Result<T, Self> {
74        Err(Self::MultipleExtensionVersion(
75            name.to_string(),
76            versions.iter().map(String::from).collect(),
77            base_path.as_ref().to_path_buf(),
78        ))
79    }
80
81    /// raise `ExtensionSqlNotExist`
82    ///
83    /// # Errors
84    ///
85    /// Always returns [`ExtensionConfigError::ExtensionSqlNotExist`].
86    pub fn extension_sql_not_exist<T, P: AsRef<Path>>(
87        extension_name: &str,
88        version: &ExtensionVersion,
89        path: P,
90    ) -> Result<T, Self> {
91        Err(Self::ExtensionSqlNotExist(
92            extension_name.to_string(),
93            version.clone(),
94            path.as_ref().to_path_buf(),
95        ))
96    }
97}
98
99#[cfg(test)]
100mod test_extension_config_error {
101    use std::path::PathBuf;
102
103    use testresult::TestResult;
104
105    use super::ExtensionConfigError;
106
107    #[test]
108    fn test_invalid_extension_name() {
109        let err: Result<(), _> = ExtensionConfigError::invalid_extension_name("name");
110        assert!(err.is_err());
111        assert!(matches!(
112            err,
113            Err(ExtensionConfigError::InvalidExtensionName(_))
114        ))
115    }
116
117    #[test]
118    fn test_invalid_extension_version() {
119        let err: Result<(), _> = ExtensionConfigError::invalid_extension_version("1.0.0");
120        assert!(err.is_err());
121        assert!(matches!(
122            err,
123            Err(ExtensionConfigError::InvalidExtensionVersion(_))
124        ));
125    }
126
127    #[test]
128    fn test_extension_not_found() {
129        let err: Result<(), _> =
130            ExtensionConfigError::extension_not_found("name", PathBuf::from("aaaa"));
131        assert!(err.is_err());
132        assert!(matches!(
133            err,
134            Err(ExtensionConfigError::ExtensionNotFound(_, _))
135        ));
136    }
137
138    #[test]
139    fn test_multiple_extension_version() {
140        let err: Result<(), _> = ExtensionConfigError::multiple_extension_version(
141            "name",
142            PathBuf::from("aaa"),
143            vec![].as_slice(),
144        );
145        assert!(err.is_err());
146        assert!(matches!(
147            err,
148            Err(ExtensionConfigError::MultipleExtensionVersion(_, _, _))
149        ))
150    }
151
152    #[test]
153    fn test_extension_sql_not_exist() -> TestResult {
154        let err: Result<(), _> = ExtensionConfigError::extension_sql_not_exist(
155            "extension_name",
156            &super::ExtensionVersion::try_from("0.1")?,
157            PathBuf::from("aaa"),
158        );
159        assert!(err.is_err());
160        assert!(matches!(
161            err,
162            Err(ExtensionConfigError::ExtensionSqlNotExist(_, _, _))
163        ));
164        Ok(())
165    }
166}