Skip to main content

hoist_core/resources/
datasource.rs

1//! Data Source resource definition
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use super::traits::{Resource, ResourceKind};
7
8/// Azure AI Search Data Source definition
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct DataSource {
12    pub name: String,
13    #[serde(rename = "type")]
14    pub datasource_type: String,
15    pub credentials: DataSourceCredentials,
16    pub container: DataSourceContainer,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub description: Option<String>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub data_change_detection_policy: Option<Value>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub data_deletion_detection_policy: Option<Value>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub encryption_key: Option<Value>,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub identity: Option<Value>,
27    #[serde(flatten)]
28    pub extra: std::collections::HashMap<String, Value>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct DataSourceCredentials {
34    /// Connection string (will be redacted in normalized output)
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub connection_string: Option<String>,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40#[serde(rename_all = "camelCase")]
41pub struct DataSourceContainer {
42    pub name: String,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub query: Option<String>,
45}
46
47impl Resource for DataSource {
48    fn kind() -> ResourceKind {
49        ResourceKind::DataSource
50    }
51
52    fn name(&self) -> &str {
53        &self.name
54    }
55
56    fn volatile_fields() -> &'static [&'static str] {
57        &["@odata.etag", "@odata.context", "credentials"]
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_datasource_kind() {
67        assert_eq!(DataSource::kind(), ResourceKind::DataSource);
68    }
69
70    #[test]
71    fn test_datasource_volatile_fields_include_credentials() {
72        let fields = DataSource::volatile_fields();
73        assert!(fields.contains(&"credentials"));
74    }
75
76    #[test]
77    fn test_datasource_deserialize() {
78        let json = r#"{
79            "name": "my-ds",
80            "type": "azureblob",
81            "credentials": { "connectionString": "secret" },
82            "container": { "name": "docs" }
83        }"#;
84        let ds: DataSource = serde_json::from_str(json).unwrap();
85        assert_eq!(ds.name, "my-ds");
86        assert_eq!(ds.datasource_type, "azureblob");
87        assert_eq!(ds.container.name, "docs");
88    }
89}